提问人:huzzm 提问时间:9/6/2020 最后编辑:p4dn24xhuzzm 更新时间:9/10/2020 访问量:422
关于将数据从设备复制到主机时的推力::execution_policy
About thrust::execution_policy when copying data from device to host
问:
我曾经在多 GPU 系统中将数据从设备传输到主机。每个 GPU 都有一个大小相等的数据分区。使用 OpenMP,我在每台设备上调用该函数。在我目前的系统上,我正在使用 4 个 GPU。thrust::copy
#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
}
在阅读了文档和以下帖子后,我了解到默认的 thrust::execution_policy 是根据传递的迭代器选择的。
将数据从设备复制到主机时,两个迭代器都作为 函数参数。
1. 默认情况下,此处选择哪种执行策略? 或?
thrust::host
thrust::device
在做了一些基准测试后,我观察到传递推力::d evice 与不传递显式相比,显式提高了性能 参数。
2. 性能提升的原因可能是什么?该系统是一台 POWER9 机器。thrust::copy和具体执行是怎么回事 政策在内部工作?每个 4 个复制引擎中有多少个 设备实际使用过吗?但是,nvprof 不显示 [CUDA memcpy DtoH] 类别 不再,而是显示 void thrust::cuda_cub::core [...] __parallel_for::P arallelForAgent [...] 甚至显示时间增加。这没有意义,因为正如我所说,我观察到 持续的性能改进(更短的总执行时间) 使用 Thrust::d evice 时。
3. 这是否只是一个 nvprof + 推力特定行为,导致分析数字与执行时间不相关?我 观察到 cudaFree 类似的东西:似乎 cudaFree 是 将控制权很快返回给主机代码,这导致 执行时间,而 NVPROF 显示的数字要高得多,因为 实际的分配可能以懒惰的方式发生。
答:
关于推力的文档声明如下:thrust::device
当设备后端为 CUDA 时,主机 API 分配的原始指针不应与 thrust::d evice 算法调用混合使用
据我了解,这意味着具有执行策略的主机设备复制首先是无效的,除非主机内存被固定。thrust::device
我们暗示您的主机分配不是固定的,但是:一种可能性是,在带有 NVLINK 的 POWER9 上,您可能很幸运,任何主机分配的内存都可以从 GPU 内部寻址。多亏了这一点,主机设备复制可以工作,尽管它不应该。thrust::device
在常规系统上,仅当主机内存分配有(固定)时,才能从 GPU 内部寻址主机内存。因此,问题在于您的 POWER 系统是否已自动升级所有要固定的分配。观察到的性能提升是由于隐式固定的内存,还是如果也使用 cudaMallocHost
显式完成分配,您是否会获得额外的加速?cudaMallocHost
另一个基于推力设计的证据表明,政策得到了支持,而没有。这与异步主机设备复制只能使用固定内存的事实非常一致。thrust::device
par.on(stream)
thrust::host
评论