diff --git a/src/common/gpu.cpp b/src/common/gpu.cpp index 4dbbee0..e34223f 100644 --- a/src/common/gpu.cpp +++ b/src/common/gpu.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "../common/global.hpp" #include "gpu.hpp" @@ -13,6 +14,22 @@ #define STRING_GIGAHERZ "GHz" #define STRING_KILOBYTES "KB" #define STRING_MEGABYTES "MB" +#define STRING_GIGABYTES "GB" + +int32_t get_value_as_smallest_unit(char ** str, uint64_t value) { + int32_t ret; + int max_len = 10; // Max is 8 for digits, 2 for units + *str = (char *) emalloc(sizeof(char)* (max_len + 1)); + + if(value/1024 >= (1 << 20)) + ret = snprintf(*str, max_len, "%.4g"STRING_GIGABYTES, (double)value/(1<<30)); + else if(value/1024 >= (1 << 10)) + ret = snprintf(*str, max_len, "%.4g"STRING_MEGABYTES, (double)value/(1<<20)); + else + ret = snprintf(*str, max_len, "%.4g"STRING_KILOBYTES, (double)value/(1<<10)); + + return ret; +} char* get_str_gpu_name(struct gpu_info* gpu) { return gpu->name; @@ -34,20 +51,57 @@ char* get_str_freq(struct gpu_info* gpu) { return string; } +// TODO: Refactor char* get_str_memory_size(struct gpu_info* gpu) { - return NULL; + char* string; + int32_t str_len = get_value_as_smallest_unit(&string, gpu->mem->size_bytes); + + if(str_len < 0) { + printBug("get_value_as_smallest_unit: %s", strerror(errno)); + return NULL; + } + + return string; } char* get_str_memory_type(struct gpu_info* gpu) { return NULL; } -char* get_str_l1(struct gpu_info* gpu) { - return NULL; +char* get_str_bus_width(struct gpu_info* gpu) { + uint32_t size = 3+1+3+1; + assert(strlen(STRING_UNKNOWN)+1 <= size); + char* string = (char *) ecalloc(size, sizeof(char)); + + sprintf(string, "%d bit", gpu->mem->bus_width); + + return string; +} + +char* get_str_memory_clock(struct gpu_info* gpu) { + // Max 10 digits and 3 for 'MHz' + uint32_t size = (10+1+3+1); + assert(strlen(STRING_UNKNOWN)+1 <= size); + char* string = (char *) ecalloc(size, sizeof(char)); + + if(gpu->mem->freq == UNKNOWN_FREQ || gpu->mem->freq < 0) + snprintf(string,strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN); + else + snprintf(string,size,"%d "STRING_MEGAHERZ, gpu->mem->freq); + + return string; } char* get_str_l2(struct gpu_info* gpu) { - return NULL; + char* string; + int32_t str_len = get_value_as_smallest_unit(&string, gpu->cach->L2->size); + + if(str_len < 0) { + printBug("get_value_as_smallest_unit: %s", strerror(errno)); + return NULL; + } + + return string; } char* get_str_peak_performance(struct gpu_info* gpu) { diff --git a/src/common/gpu.hpp b/src/common/gpu.hpp index 89ea9ec..9c58096 100644 --- a/src/common/gpu.hpp +++ b/src/common/gpu.hpp @@ -27,7 +27,6 @@ struct cach { }; struct cache { - struct cach* L1; struct cach* L2; }; @@ -38,8 +37,10 @@ struct topology { }; struct memory { - int32_t size_bytes; + int64_t size_bytes; MEMTYPE type; + int32_t bus_width; + int32_t freq; }; struct gpu_info { @@ -59,7 +60,8 @@ char* get_str_gpu_name(struct gpu_info* gpu); char* get_str_freq(struct gpu_info* gpu); char* get_str_memory_size(struct gpu_info* gpu); char* get_str_memory_type(struct gpu_info* gpu); -char* get_str_l1(struct gpu_info* gpu); +char* get_str_bus_width(struct gpu_info* gpu); +char* get_str_memory_clock(struct gpu_info* gpu); char* get_str_l2(struct gpu_info* gpu); char* get_str_peak_performance(struct gpu_info* gpu); diff --git a/src/common/main.cpp b/src/common/main.cpp index 6609162..88a974d 100644 --- a/src/common/main.cpp +++ b/src/common/main.cpp @@ -64,7 +64,8 @@ int main(int argc, char* argv[]) { printf("CUDA cores: %d\n", get_str_cuda_cores(gpu)); printf("Memory size: %s\n", get_str_memory_size(gpu)); printf("Memory type: %s\n", get_str_memory_type(gpu)); - printf("L1 size: %s\n", get_str_l1(gpu)); + printf("Memory frequency: %s\n", get_str_memory_clock(gpu)); + printf("Bus width: %s\n", get_str_bus_width(gpu)); printf("L2 size: %s\n", get_str_l2(gpu)); printf("Peak performance: %s\n", get_str_peak_performance(gpu)); diff --git a/src/cuda/cuda.cpp b/src/cuda/cuda.cpp index 5e59e5a..d1e213e 100644 --- a/src/cuda/cuda.cpp +++ b/src/cuda/cuda.cpp @@ -6,9 +6,14 @@ #include "uarch.hpp" #include "../common/global.hpp" -struct cache* get_cache_info(struct gpu_info* gpu) { +struct cache* get_cache_info(struct gpu_info* gpu, cudaDeviceProp prop) { struct cache* cach = (struct cache*) emalloc(sizeof(struct cache)); + cach->L2 = (struct cach*) emalloc(sizeof(struct cach)); + cach->L2->size = prop.l2CacheSize; + cach->L2->num_caches = 1; + cach->L2->exists = true; + return cach; } @@ -22,9 +27,13 @@ struct topology* get_topology_info(struct gpu_info* gpu, cudaDeviceProp prop) { return topo; } -struct memory* get_memory_info(struct gpu_info* gpu) { +struct memory* get_memory_info(struct gpu_info* gpu, cudaDeviceProp prop) { struct memory* mem = (struct memory*) emalloc(sizeof(struct memory)); + mem->size_bytes = (unsigned long long) prop.totalGlobalMem; + mem->freq = prop.memoryClockRate * 1e-3f; + mem->bus_width = prop.memoryBusWidth; + return mem; } @@ -53,7 +62,8 @@ struct gpu_info* get_gpu_info() { } gpu->arch = get_uarch_from_cuda(gpu); - gpu->cach = get_cache_info(gpu); + gpu->cach = get_cache_info(gpu, deviceProp); + gpu->mem = get_memory_info(gpu, deviceProp); gpu->topo = get_topology_info(gpu, deviceProp); gpu->peak_performance = get_peak_performance(gpu);