Cuda pagelocked状态是否对使用同一设备的所有主机线程可见?

Cuda pagelocked状态是否对使用同一设备的所有主机线程可见?,cuda,Cuda,假设我有如下代码: cudaHostAlloc( (void**)&pagelocked_ptr, size, cudaHostAllocDefault ) #pragma omp parallel num_threads(num_streams) { ... cudaMemcpyAsync( pagelocked_ptr + offset_thisthread , src , count

假设我有如下代码:

cudaHostAlloc( (void**)&pagelocked_ptr, size, cudaHostAllocDefault )
#pragma omp parallel num_threads(num_streams)
{ 
  ...
  cudaMemcpyAsync( pagelocked_ptr + offset_thisthread
                 , src
                 , count
                 , kind
                 , stream_thisthread );
  ...
}
注意,我在这里明确避免设置标志
cudaHostAllocPortable
。每个线程使用自己的流,并且(我相信)隐式地选择默认的Cuda设备

根据Cuda示例第11.4节

页面看起来只能固定到单个CPU线程。也就是说,如果任何线程已将它们分配为固定内存,它们将保持页面锁定,但它们将只显示为对分配它们的线程进行页面锁定

他们接着说,设置
cudaHostAllocPortable
可以解决这个问题,并允许所有线程将分配识别为固定缓冲区。因此,除非我指定
cudaHostAllocPortable
而不是
cudaHostAllocDefault
,否则上面的
cudaMemcpyAsync
调用将失败

Cuda C指南似乎与此信息冲突。我的假设是Cuda上下文跟踪主机内存的哪些区域被页面锁定,并且可以在没有中间暂存拷贝的情况下传输到设备。根据当前Cuda C指南和

此设备的主上下文…在应用程序的所有主机线程之间共享

默认情况下,使用上述页面锁定内存的好处仅与分配块时的当前设备(以及共享相同统一地址空间的所有设备,如果有的话…)结合使用

这似乎意味着分配的页面锁定性质是通过跨不同线程的Cuda调用知道的,因为它们都使用设备0,并且在所有线程中调用
cudaMemcpyAsync()
都会成功。换句话说,如果我的解释正确,那么只有在尝试在Cuda上下文之间共享页面锁定内存时(例如,在使用
cudaSetDevice
在GPU之间切换,并将页面锁定分配的一块卸载到每个GPU时),才需要设置
cudaHostAllocPortable

Cuda示例中的信息是否已过时?塔龙对各国的答复

在CUDA 4之前,上下文不是线程安全的,需要通过上下文迁移API显式迁移

但我不确定这是如何影响页面锁定状态对来自不同线程的Cuda调用的可见性的


提前感谢您的帮助

对于在特定设备上使用相同上下文的所有线程,pagelocked状态应该是明显的。如果您正在使用运行时API(正如您在这里所做的),那么每个进程中每个设备通常只有一个上下文,因此该进程中的所有线程都应该在特定设备上共享相同的上下文,并且具有该上下文中任何指针的相同视图

cudaHostAllocPortable
标志的功能之一如所述:

此调用返回的内存将被所有CUDA上下文视为固定内存,而不仅仅是执行分配的上下文


这意味着在多上下文设置或多设备设置中(上下文对于特定设备是唯一的),必须使用此标志在进程可见的所有上下文中从该指针获取固定行为。

对于在特定设备上使用相同上下文的所有线程,pagelocked状态应该是明显的。如果您正在使用运行时API(正如您在这里所做的),那么每个进程中每个设备通常只有一个上下文,因此该进程中的所有线程都应该在特定设备上共享相同的上下文,并且具有该上下文中任何指针的相同视图

cudaHostAllocPortable
标志的功能之一如所述:

此调用返回的内存将被所有CUDA上下文视为固定内存,而不仅仅是执行分配的上下文

这意味着,在多上下文设置或多设备设置(特定设备的上下文是唯一的)中,有必要使用此标志在进程可见的所有上下文中从该指针获取固定行为