我正试图寻找我程序中的一个错误。它产生cudaMalloc在不同的CPU线程上返回相同的内存地址
[vaio:10404] Signal: Segmentation fault (11)
[vaio:10404] Signal code: Address not mapped (1)
[vaio:10404] Failing at address: 0x210000
[vaio:10405] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x7fa7857ffcb0]
[vaio:10405] [ 1] /lib/x86_64-linux-gnu/libc.so.6(+0x14fe20) [0x7fa785580e20]
[vaio:10405] [ 2] /usr/lib/libcuda.so.1(+0x1b1f49) [0x7fa78676bf49]
0x210000
是住在GPU内存中的地址。我没有统一的地址空间(由于卡片限制:sm_12)。
通过mpiexec -n 2
运行程序时发生此问题。也就是说,我启动了2个CPU进程,都在相同的(!)GPU上创建了自己的上下文(仅安装了1个GPU)。就像这样:
cuInit(0);
cuDeviceGet(&cuDevice, 0); // get device number 0
cuCtxCreate(&cuContext, 0, cuDevice); // create context
cuMemAlloc(&mem , size); // allocate memory pool (hundreds of MB)
(这是在这里简单 - 所有CUDA调用检查错误返回)
我使用这个设置很成功很长一段时间,现在(多个主机进程共享相同的GPU) 。但是,那是使用CUDA运行时API的时候。现在,我切换到驱动程序API。
为了追捕这件事,我把上面代码的mem
转储出来。原来,cuMemAlloc
返回的内存地址在两个进程中都是相同的!这让我想起了我。这里转储出:
process 0: allocate internal buffer: unaligned ptr = 0x210000 aligned ptr = 0x210000
process 1: allocate internal buffer: unaligned ptr = 0x210000 aligned ptr = 0x210000
立即我用我的旧代码(运行时API)检查,从来没有这样的问题。原来它报告两个进程(共享相同的设备)相同的内存地址。这从未引起我的注意。
我觉得这很难相信。只是为了清楚:两个进程都要求设备内存有cudaMalloc
(运行时API)和cuMalloc
(驱动程序API)(大卡上有400MB),并且两个进程都返回相同的地址? 我相信没有一个进程正在前进很多并且已经释放内存,因此第一个进程可以重用相同的内存,因为第一个进程已经终止。不,这个内存用作内存池来为后续的内存分配提供服务,并且它们之间有很多同步点。池在程序终止时被释放。
任何人都知道如何将相同的指针值(内存地址)报告给两个进程,但在GPU上这是指不同的内存? (因为它执行的计算是正确的,如果内存池重叠,情况就不会这样)。据我所知,这是不可能的。我错过了什么?
伟大的问题,+1。 –
talonmies是对的。这与在两个不同的CPU进程中获取相同地址没有区别。 – ArchaeaSoftware