Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
cudaMalloc在不同的CPU线程上返回相同的内存地址_C_Cuda_Mpi_Memory Address - Fatal编程技术网

cudaMalloc在不同的CPU线程上返回相同的内存地址

cudaMalloc在不同的CPU线程上返回相同的内存地址,c,cuda,mpi,memory-address,C,Cuda,Mpi,Memory Address,我正在努力查找程序中的一个bug。它产生 [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:104

我正在努力查找程序中的一个bug。它产生

[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-n2
运行程序时出现问题。也就是说,我启动两个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),它从未出现过这样的问题。结果表明,它在两个进程(共享同一设备)上报告相同的内存地址。这以前从未引起我的注意

我觉得这很难相信。只是想说明一下:这两个进程都使用
cudamaloc
(运行时API)和
cumaloc
(驱动程序API)(在一个大卡上为400MB)请求设备内存,并且这两个进程都返回了相同的地址? 我确信没有一个进程进步过多并且已经释放了内存,因此第一个进程可以重用相同的内存,因为第一个进程已经终止。不,该内存用作内存池,用于后续内存分配,其间有许多同步点。该池在程序终止时被释放


有人知道如何向两个进程报告相同的指针值(内存地址),但在GPU上这指的是不同的内存吗?(必须是这样,因为它执行的计算是正确的。如果内存池重叠,情况就不会是这样了)。据我所知,这是不可能的。我遗漏了什么?

您遗漏了虚拟寻址的概念


每个CPU线程都有自己的CUcontext,每个CUcontext都有自己的GPU虚拟地址空间。从API返回的地址是虚拟的,主机驱动程序和/或设备将虚拟地址转换为GPU内存中的绝对地址。有大量证据表明,GPU板上有专门的TLB用于此目的。

这将假定成功的
cumaloc
在不同的CPU线程上返回相同的值是可能的。由于虚拟到真实地址的映射是在专用硬件的帮助下完成的(如您所说),因此无法从应用程序的角度来区分真实地址。@弗兰克:是的,这就是为什么一些GPU API使用不透明的缓冲区对象来表示内存分配,而不是裸指针的原因。应用程序不应该或者不需要非常了解GPU地址的含义。这与在两个不同的CPU进程中获得相同的地址没有什么不同。