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

About thrust::execution_policy when copying data from device to host

提问人:huzzm 提问时间:9/6/2020 最后编辑:p4dn24xhuzzm 更新时间:9/10/2020 访问量:422

问:

我曾经在多 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::hostthrust::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 显示的数字要高得多,因为 实际的分配可能以懒惰的方式发生。

C++ CUDA 基准测试 GPGPU 推力

评论


答:

1赞 Dmitry Mikushin 9/10/2020 #1

关于推力的文档声明如下:thrust::device

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

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

我们暗示您的主机分配不是固定的,但是:一种可能性是,在带有 NVLINK 的 POWER9 上,您可能很幸运,任何主机分配的内存都可以从 GPU 内部寻址。多亏了这一点,主机设备复制可以工作,尽管它不应该。thrust::device

在常规系统上,仅当主机内存分配有(固定)时,才能从 GPU 内部寻址主机内存。因此,问题在于您的 POWER 系统是否已自动升级所有要固定的分配。观察到的性能提升是由于隐式固定的内存,还是如果也使用 cudaMallocHost 显式完成分配,您是否会获得额外的加速?cudaMallocHost

另一个基于推力设计的证据表明,政策得到了支持,而没有。这与异步主机设备复制只能使用固定内存的事实非常一致。thrust::devicepar.on(stream)thrust::host

评论

1赞 Robert Crovella 9/17/2020
power9 具有 ATS 功能,允许主机分配的指针(无论是否固定)可从主机或设备代码中取消引用,但可能会对性能产生负面影响