【问题标题】:How to allocate all available global memory on the GeForce GTX 690 device?如何在 GeForce GTX 690 设备上分配所有可用的全局内存?
【发布时间】:2013-02-06 03:34:45
【问题描述】:

现在我需要使用 cuda 技术分配所有可用内存。 我用 Tesla C2050、Quadro 600 和 GeForce GTX 560 Ti 做到这一点: 首先,我在设备上分配了 0 字节的全局内存。第二步是通过 cudaMemGetInfo 函数定义设备的可用内存并分配该可用内存。它适用于上面列出的设备。 但这种机制不适用于 GeForce GTX 690。

有人可以帮我吗,我可以使用什么机制在 GeForce GTX 690 设备上分配内存或该操作的任何范例?

看起来像这样:

cudaSetDevice(deviceIndex);

int (*reservedMemory);

cudaMalloc(&reservedMemory, 0);

size_t freeMemory, totalMemory;

cudaMemGetInfo(&freeMemory, &totalMemory);

cudaMalloc(&reservedMemory, freeMemory);

在 GeForce GTX 690 上,现有的两个流式多处理器之一在 2147483648 字节的内存上运行,但我只能分配 1341915136 字节的空闲全局内存,即 2050109440 字节。 在 Quadro 600 上,一个现有的流式多处理器在 1073414144 字节内存上运行,我可以分配所有可用的 859803648 字节可用全局内存,即 859803648 字节。

以 Quadro 600 为例(显示编译、链接和执行过程):

D:\Gdmt> nvcc -arch=compute_20 -code=sm_21 -c ./Gdmt.cu -o ./Gdmt.obj
Gdmt.cu
tmpxft_00000bb4_00000000-3_Gdmt.cudafe1.gpu
tmpxft_00000bb4_00000000-8_Gdmt.cudafe2.gpu
Gdmt.cu
tmpxft_00000bb4_00000000-3_Gdmt.cudafe1.cpp
tmpxft_00000bb4_00000000-14_Gdmt.ii

D:\Gdmt> nvcc ./Gdmt.obj -o ./Gdmt.exe

D:\Gdmt> nvcc -arch=compute_20 -code=sm_21 -c ./Gdmt_additional.cu -o ./Gdmt_add
itional.obj
Gdmt_additional.cu
tmpxft_00000858_00000000-3_Gdmt_additional.cudafe1.gpu
tmpxft_00000858_00000000-8_Gdmt_additional.cudafe2.gpu
Gdmt_additional.cu
tmpxft_00000858_00000000-3_Gdmt_additional.cudafe1.cpp
tmpxft_00000858_00000000-14_Gdmt_additional.ii

D:\Gdmt> nvcc ./Gdmt_additional.obj -o ./Gdmt_additional.exe

D:\Gdmt> Gdmt.exe
Total amount of memory: 1073414144 Bytes;
Memory to reserve: 859803648 Bytes;
Memory reserved: 859803648 Bytes;
^C
D:\Gdmt> Gdmt_additional.exe
Allocation is succeeded on 890830848 bytes of reserved memory.
^C
D:\Gdmt>

以 GeForce GTX 690 为例(显示编译、链接和执行过程):

J:\Gdmt> nvcc -arch=compute_30 -code=sm_30 -c ./Gdmt.cu -o ./Gdmt.obj
Gdmt.cu
tmpxft_000011f0_00000000-5_Gdmt.cudafe1.gpu
tmpxft_000011f0_00000000-10_Gdmt.cudafe2.gpu
Gdmt.cu
tmpxft_000011f0_00000000-5_Gdmt.cudafe1.cpp
tmpxft_000011f0_00000000-15_Gdmt.ii

J:\Gdmt> nvcc ./Gdmt.obj -o ./Gdmt.exe

J:\Gdmt> nvcc -arch=compute_30 -code=sm_30 -c ./Gdmt_additional.cu -o ./Gdmt_add
itional.obj
Gdmt_additional.cu
tmpxft_00001164_00000000-5_Gdmt_additional.cudafe1.gpu
tmpxft_00001164_00000000-10_Gdmt_additional.cudafe2.gpu
Gdmt_additional.cu
tmpxft_00001164_00000000-5_Gdmt_additional.cudafe1.cpp
tmpxft_00001164_00000000-15_Gdmt_additional.ii

J:\Gdmt> nvcc ./Gdmt_additional.obj -o ./Gdmt_additional.exe

J:\Gdmt> Gdmt.exe
Total amount of memory: 2147483648 Bytes;
Memory to reserve: 2050109440 Bytes;
Warning, memory allocation process is not succeeded!
^C
J:\Gdmt> Gdmt_additional.exe
Allocation is succeeded on 1341915136 bytes of reserved memory.
^C

示例已存档并位于:

(z7 存档 - 78.5 KB ~ 80,434 字节) https://docs.google.com/file/d/0BzZ5q0v8n-qTTDctVDV5Mnh2ODA/edit (zip 存档 - 163 KB ~ 167,457 字节) https://docs.google.com/file/d/0BzZ5q0v8n-qTT2xoV3NXSzhQMDQ/edit

此主题是在“The GeForce Lounge”和“CUDA Programming and Performance”上发布的同名主题的克隆。

【问题讨论】:

  • 您显然是在 Windows 主机上运行它。您提到的其他设备是否也在 Windows 主机上运行?此外,您还展示了用于编译为计算 2.0 目标的构建过程。如果为计算 3.0 目标编译,GTX690 的行为是否相同?
  • 所以您可以在其中一个 GTX 690 子 gpu 上分配 2GB,而在另一个子 gpu 上分配大约 1.3GB?如果是,我的第一个猜测是使用这个 sub gpu 作为显卡,它会占用一些内存(虽然 700MB 会有点多)。
  • 感谢 talonmies 和 GeorgT。 talonmies,首先 - 是的,我使用 Windows 作为此设备的操作系统平台,其次 - 在上面显示的构建过程中,计算编号 2.0 的目标适用于 Quadro 600 设备,计算编号 3.0 的目标适用于 GeForce GTX 690 设备。 GeorgT - 不,我可以在两个使用 GeForce GTX 690 设备的现有流式多处理器上分配 1.3 * 8^9.98(9.98 是 8 的度数)字节的全局内存。

标签: cuda nvidia


【解决方案1】:

我可以重新运行您的示例并得出相同的结果。

我试图从另一边解决这个问题,并尝试分配大小递减的块。

int (*reservedMemory);
size_t const NBlockSize = 1300 *1024*1024; 
size_t freeMemory, totalMemory;
cudaError_t nErr = cudaSuccess;
size_t nTotalAlloc=0;
while( nErr == cudaSuccess )
{
    cudaMemGetInfo(&freeMemory, &totalMemory);
    std::cout << "===========================================================" << std::endl;
    std::cout << "Free/Total(kB): " << freeMemory/1024 << "/" << totalMemory/1024 << std::endl;

    size_t nAllocSize = NBlockSize;
    while( nAllocSize > freeMemory )
        nAllocSize /= 2;

    nErr = cudaMalloc(&reservedMemory, nAllocSize );
    if( nErr == cudaSuccess )
        nTotalAlloc += nAllocSize;
    std::cout << "AllocSize(kB): " << nAllocSize/1024 << ", error: " << cudaGetErrorString(nErr) << std::endl;

}
std::cout << "TotalAlloc/Total (kB): " << nTotalAlloc/1024 << "/" << totalMemory/1024 << std::endl;

程序从一个大小为 NBlockSize 的块开始,如果 freeMemory 减少,也减少 nAllocSize。查看下面的输出,在分配与 freeMemory 有很大关系的块时,cudaMalloc 的行为似乎有点不可预测。在某一时刻,它设法分配了超过 98% 的可用内存,在另一时刻,它未能从 1GB 可用内存中分配 800MB。

最有趣的运行是起始块大小为 700MB 的运行。在上一次成功的循环中,它设法在 1428 中分配 1400kB,但在下一次运行中分配 20kB 中的 10 时失败。

根据起始大小,程序在最佳运行时设法分配了除 8kB 之外的所有可用空间,在最坏的情况下剩余 1 GB。

D:\Buildx64\Test\GMDT\Debug>Gdmt.exe
NBlockSize(MB): 1000
===========================================================
Free/Total(kB): 1797120/2097152
AllocSize(kB): 1024000, percentage of freememory: 0.569801, error: no error
===========================================================
Free/Total(kB): 773120/2097152
AllocSize(kB): 512000, percentage of freememory: 0.662252, error: no error
===========================================================
Free/Total(kB): 261120/2097152
AllocSize(kB): 256000, percentage of freememory: 0.980392, error: no error
===========================================================
Free/Total(kB): 5128/2097152
AllocSize(kB): 4000, percentage of freememory: 0.780031, error: no error
===========================================================
Free/Total(kB): 1032/2097152
AllocSize(kB): 1000, percentage of freememory: 0.968992, error: no error
===========================================================
Free/Total(kB): 8/2097152
AllocSize(kB): 7, percentage of freememory: 0.976563, error: out of memory
TotalAlloc/Total (kB): 1797000/2097152


D:\Buildx64\Test\GMDT\Debug>Gdmt.exe
NBlockSize(MB): 1200
===========================================================
Free/Total(kB): 1796864/2097152
AllocSize(kB): 1228800, percentage of freememory: 0.683858, error: no error
===========================================================
Free/Total(kB): 568072/2097152
AllocSize(kB): 307200, percentage of freememory: 0.540777, error: no error
===========================================================
Free/Total(kB): 260872/2097152
AllocSize(kB): 153600, percentage of freememory: 0.588795, error: no error
===========================================================
Free/Total(kB): 107272/2097152
AllocSize(kB): 76800, percentage of freememory: 0.715937, error: no error
===========================================================
Free/Total(kB): 30472/2097152
AllocSize(kB): 19200, percentage of freememory: 0.630087, error: no error
===========================================================
Free/Total(kB): 11272/2097152
AllocSize(kB): 9600, percentage of freememory: 0.851668, error: no error
===========================================================
Free/Total(kB): 1672/2097152
AllocSize(kB): 1200, percentage of freememory: 0.717703, error: no error
===========================================================
Free/Total(kB): 392/2097152
AllocSize(kB): 300, percentage of freememory: 0.765306, error: out of memory
TotalAlloc/Total (kB): 1796400/2097152

D:\Buildx64\Test\GMDT\Debug>Gdmt.exe
NBlockSize(MB): 800
===========================================================
Free/Total(kB): 1844448/2097152
AllocSize(kB): 819200, percentage of freememory: 0.444144, error: no error
===========================================================
Free/Total(kB): 1025248/2097152
AllocSize(kB): 819200, percentage of freememory: 0.799026, error: out of memory
TotalAlloc/Total (kB): 819200/2097152

D:\Buildx64\Test\GMDT\Debug>Gdmt.exe
NBlockSize(MB): 700
===========================================================
Free/Total(kB): 1835528/2097152
AllocSize(kB): 716800, percentage of freememory: 0.390514, error: no error
===========================================================
Free/Total(kB): 1118740/2097152
AllocSize(kB): 716800, percentage of freememory: 0.640721, error: no error
===========================================================
Free/Total(kB): 401940/2097152
AllocSize(kB): 358400, percentage of freememory: 0.891675, error: no error
===========================================================
Free/Total(kB): 43540/2097152
AllocSize(kB): 22400, percentage of freememory: 0.514469, error: no error
===========================================================
Free/Total(kB): 21140/2097152
AllocSize(kB): 11200, percentage of freememory: 0.529801, error: no error
===========================================================
Free/Total(kB): 9876/2097152
AllocSize(kB): 5600, percentage of freememory: 0.567031, error: no error
===========================================================
Free/Total(kB): 4244/2097152
AllocSize(kB): 2800, percentage of freememory: 0.659755, error: no error
===========================================================
Free/Total(kB): 1428/2097152
AllocSize(kB): 1400, percentage of freememory: 0.980392, error: no error
===========================================================
Free/Total(kB): 20/2097152
AllocSize(kB): 10, percentage of freememory: 0.546875, error: out of memory
TotalAlloc/Total (kB): 1835400/2097152

【讨论】:

  • 我有一台 GTX660,显然有 2GB 的 RAM。使用 sm_30 和 compute_30 编译。
  • 内存大小输出通过整数除法得到。
  • 我在安装了 cuda 5.0 的 Ubuntu 11.10 (amd64) 上对此进行了测试,结果是前面描述的算法,首先分配零字节内存来初始化设备,然后可用内存的其余部分- 不工作。我们可以保留所有可用内存,但在 GeForce GTX 690 上没有 1 兆字节。
【解决方案2】:

我最近想起了 cuda 中的“页面锁定”机制。我对其进行了测试,并没有得到令人满意的性能结果(使用这种机制的计算速度要慢十倍,然后是带有 GeForce GTX 690 的 Windows 的内存保留功能非常有限的版本)。我只是以为将数据复制到设备以供以后计算和写回会自动完成,但实际上并没有涉及设备的内存。

【讨论】:

  • 不知道是不是GeForce GTX Titan在Windows操作系统下的问题。
猜你喜欢
  • 2013-04-04
  • 2012-12-16
  • 2014-11-25
  • 1970-01-01
  • 2016-10-16
  • 2010-09-09
  • 1970-01-01
  • 2013-11-09
相关资源
最近更新 更多