关于从设备向主机复制数据时的推力:: execution_policy

问题描述

我使用thrust::copy在多GPU系统中将数据从设备传输到主机。每个GPU都有大小相等的数据分区。使用OpenMP,我在每个设备上调用该函数。在当前系统上,我正在使用4个GPU。

#pragma omp parallel for
for (size_t i = 0; i < devices.size(); ++i) 
{
    const int device = devices[i];
    thrust::copy(thrust::device,// execution policy
                 device_buffers->At(device)->begin(),// thrust::device_vector
                 device_buffers->At(device)->end(),elements->begin() + (device * block_size)); // thrust::host_vector
}

在阅读了文档和下面的post之后,我了解到默认的push :: execution_policy是根据传递的迭代器选择的。

  • 将数据从设备复制到主机时,两个迭代器均以 功能参数。

    1。默认情况下,在这里选择哪种执行策略? thrust::hostthrust::device

  • 做完一些基准测试后,我观察到传递了push :: device 与未通过显式测试相比,显着提高了性能 参数。
    2。性能提高的原因可能是什么?该系统是一台POWER9机器。如何推力::复制和具体执行 内部政策工作? 每个4个复制引擎中有多少个 设备是实际使用的吗?

  • 但是,nvprof不显示[CUDA memcpy DtoH]类别 不再显示虚空推力:: cuda_cub :: core [...] __parallel_for :: ParallelForAgent [...]甚至显示时间增加。这没有道理,因为正如我所说,我观察到 持续改进性能(缩短总执行时间) 在使用推力::设备时。

    3。这仅仅是nvprof +特定于推力的行为,导致性能分析数字与正常执行时间不相关吗? 观察到与cudaFree类似的东西:似乎cudaFree是 很快将控制权返回给主机代码,这导致了 执行时间,而nvprof显示的数字要高得多,因为 实际的释放可能以懒惰的方式发生。

解决方法

thrust::device上的推力doc指出:

当设备后端为CUDA时,主机API分配的原始指针不应与推力::设备算法调用混合使用

据我了解,这首先意味着具有thrust::device执行策略的主机设备副本无效,除非固定了主机内存。

我们暗示您的主机分配没有固定,但是::一种可能性是在带有NVLINK的POWER9上,您可能很幸运,可以从GPU内寻址任何主机分配的内存。因此,使用thrust::device的主机设备副本可以正常工作,尽管不应该。

在常规系统上,仅当此主机内存分配有cudaMallocHost(固定)时,才可以在GPU内对主机内存进行寻址。因此,问题是您的POWER系统是否已自动升级了所有要固定的分配。如果还使用cudaMallocHost进行了显式分配,那么观察到的性能收益是归因于隐式固定的内存,还是获得额外的加速?

另一个基于推力设计的证据是thrust::device策略获得了par.on(stream)的支持,而thrust::host没有。这与只有在固定内存下才可以进行异步主机设备复制这一事实基本吻合。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...