我在opencl实施中使用了Intel集成gpu。我正在实现一个零拷贝的程序,其中我没有将数据复制到gpu,而是共享了公共内存(RAM)。
我有一个64位的CPU,但是在GPU规格中,它显示只有32位的寻址模式。
我在gpu和cpu之间共享一个malloc堆空间,当我打印地址时,我看到以下内容。
在GPU中:
if(id==0){
printf("Mem address: %p\n",A);
//Outputs Mem address: 0x1010000
在CPU中:它会打印
printf("Outside Mem address: %p\n",cpuA);
Device: Intel(R) HD Graphics IvyBridge M GT2
Outside Mem address: 0x7fcd529d9000
我不知道如何在gpu中映射它。我想知道2 ^ 28/2 ^ 32是gpu可以访问的最大地址吗?
答案 0 :(得分:3)
您要在主机上打印的内存地址是一个虚拟地址,该地址仅在程序进程的上下文中才有意义。在CPU this is transparently translated to a physical RAM page中,其地址与虚拟地址无关,但存储在操作系统维护的查找表(页表)中。请注意,“ 64位CPU”通常是指虚拟地址中的位数。 (尽管许多64位CPU实际上忽略了8-16位。)物理地址(用于寻址物理RAM单元和映射的设备内存)的位数通常少得多,只有40位。
连接到系统并能够执行直接内存访问(DMA)的设备通常处理物理内存地址。如果您的Intel GPU没有内部内存映射方案(并且没有IOMMU处于活动状态,请参阅下文),则您在OpenCL内核代码中看到的地址可能是物理内存地址。如果设备只能寻址32位,则意味着它只能访问系统中 physical 内存的前4GiB。通过为不受32位限制影响的设备和用户空间进程分配4GiB以上的内存,或通过使用“反弹缓冲区”,操作系统可以安排受限制设备使用的所有缓冲区位于该内存中区域,无论虚拟地址如何。
最近,IOMMU已变得很普遍。这些还引入了类似于 device 的虚拟内存(如映射系统)-因此,设备看到的内存地址再次与它们所对应的系统内存的物理地址无关。这主要是一项安全功能-理想情况下,每个设备都有其自己的地址空间,因此设备不会意外或故意访问不应访问的系统内存。这也意味着32位限制变得完全无关紧要,因为每个设备都有自己的32位地址空间,该地址空间可以映射到4GiB边界之外的物理内存。