当 CPU 尝试读取由 GPU 初始化的托管内存时,为啥数据会从主机迁移到设备?

Posted

技术标签:

【中文标题】当 CPU 尝试读取由 GPU 初始化的托管内存时,为啥数据会从主机迁移到设备?【英文标题】:Why data migrate from Host to Device when CPU try to read a managed memory initialized by GPU?当 CPU 尝试读取由 GPU 初始化的托管内存时,为什么数据会从主机迁移到设备? 【发布时间】:2020-12-07 08:05:39 【问题描述】:

在下面的测试代码中,我们通过 GPU 初始化数据,然后通过 CPU 访问数据。我对 nvprof 的分析结果有 2 个问题。

为什么会有一个数据从主机迁移到设备?据我了解,它应该是设备到主机。

为什么 H->D 计数是 2?我认为应该是 1,因为数据在一页中。

提前致谢!

我的环境

驱动版本:418.87.00 CUDA 版本:10.1 ubuntu 18.04
#include <cuda.h>
#include <iostream>

using namespace std;

__global__ void setVal(char* data, int idx)

    data[idx] = 'd';



int main()

    const int count =  8;

    char* data;
    cudaMallocManaged((void **)&data, count);

    setVal<<<1,1>>>(data, 0); //GPU page fault

    cout<<" cpu read " << data[0] <<endl; 
  
    cudaFree(data);

    return 0;

==28762== Unified Memory profiling result:
Device "GeForce GTX 1070 (0)"
   Count  Avg Size  Min Size  Max Size  Total Size  Total Time  Name
       2  32.000KB  4.0000KB  60.000KB  64.00000KB  11.74400us  Host To Device
       1         -         -         -           -  362.9440us  Gpu page fault groups
Total CPU Page faults: 1

【问题讨论】:

【参考方案1】:

为什么会有一个数据从主机迁移到设备?据我了解,它应该是设备到主机。

您正在主机和设备之间颠簸数据。因为 GPU 内核启动是异步的,所以您的主机代码在内核启动之后实际上是在访问 GPU 代码之前之前的数据。

在你的内核调用之后放置一个cudaDeviceSynchronize(),这样CPU代码在内核完成之前不会尝试读取数据。

对于您的其他问题,我没有答案。探查器通常无法完美解析非常少量的活动。它不一定会在分析运行期间检测所有 SM,并且它的一些结果可能会针对 GPC、TPC 和/或整个 GPU 的大小进行缩放。这将是我的猜测,尽管这只是猜测。在分析几乎什么都不做的微小代码时,我通常不期望分析器提供完全准确的结果。

【讨论】:

以上是关于当 CPU 尝试读取由 GPU 初始化的托管内存时,为啥数据会从主机迁移到设备?的主要内容,如果未能解决你的问题,请参考以下文章

我如何与Metal沟通,以避免GPU和CPU之间的数据冲突

CPU是怎样读取内存和显存信息的?显存的信息通不通过内存?

gpu性能和gpu内存

tensorflow小记2

初始化模型时 GPU 内存不足

使用 Colab GPU 时出错,而 CPU 则没有