我正在使用cudaMemGetInfo来获取系统当前使用的vram。
extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *free, size_t *total);
我遇到两个问题:
主要是当图形设备几乎没有可用于分配的内存时,返回的空闲值才正确。否则,即使GPU-Z清楚地表明使用了大约80%的内存,它仍然使用大约20%的内存。当我达到95%的内存时,cudaMemGetInfo会突然返回一个好的值。请注意,总内存始终是正确的。
第二个问题是,只要我使用该功能,就会分配视频内存。至少40mbytes但在一些图形设备上可以达到400。
我的代码:
#include <cuda_runtime.h>
size_t Profiler::GetGraphicDeviceVRamUsage(int _NumGPU)
{
cudaSetDevice(_NumGPU);
size_t l_free = 0;
size_t l_Total = 0;
cudaError_t error_id = cudaMemGetInfo(&l_free, &l_Total);
return (l_Total - l_free);
}
我尝试了5种不同的nvidia图形设备。问题总是一样的。
有什么想法吗?
答案 0 :(得分:0)
关于你的第一点,我无法重现这一点。如果我将您的代码扩展为完整的示例:
#include <iostream>
size_t GetGraphicDeviceVRamUsage(int _NumGPU)
{
cudaSetDevice(_NumGPU);
size_t l_free = 0;
size_t l_Total = 0;
cudaError_t error_id = cudaMemGetInfo(&l_free, &l_Total);
return (l_Total - l_free);
}
int main()
{
const size_t sz = 1 << 20;
for(int i=0; i<20; i++) {
size_t before = GetGraphicDeviceVRamUsage(0);
char *p;
cudaMalloc((void **)&p, sz);
size_t after = GetGraphicDeviceVRamUsage(0);
std::cout << i << " " << before << "->" << after << std::endl;
}
return cudaDeviceReset();
}
我在linux机器上得到这个:
$ ./meminfo
0 82055168->83103744
1 83103744->84152320
2 84152320->85200896
3 85200896->86249472
4 86249472->87298048
5 87298048->88346624
6 88346624->89395200
7 89395200->90443776
8 90443776->91492352
9 91492352->92540928
10 92540928->93589504
11 93589504->94638080
12 94638080->95686656
13 95686656->96735232
14 96735232->97783808
15 97783808->98832384
16 98832384->99880960
17 99880960->100929536
18 100929536->101978112
19 101978112->103026688
我在Windows WDDM机器上得到了这个:
>meminfo
0 64126976->65175552
1 65175552->66224128
2 66224128->67272704
3 67272704->68321280
4 68321280->69369856
5 69369856->70418432
6 70418432->71467008
7 71467008->72515584
8 72515584->73564160
9 73564160->74612736
10 74612736->75661312
11 75661312->76709888
12 76709888->77758464
13 77758464->78807040
14 78807040->79855616
15 79855616->80904192
16 80904192->81952768
17 81952768->83001344
18 83001344->84049920
19 84049920->85098496
两者似乎都与我保持一致。
关于你的第二点:cudaSetDevice
在你传递给它的设备号上建立一个CUDA上下文,如果没有上下文的话。建立CUDA上下文将为运行CUDA代码所需的运行时组件保留内存。因此,如果它是第一个包含您调用的函数的CUDA API,则调用该函数将消耗内存是完全正常的。