【问题标题】:How can I improve performance for memory usage?如何提高内存使用性能?
【发布时间】:2016-01-10 19:18:54
【问题描述】:

我有一些数据:

MyDataType *deviceData, *hostData;

我为主机数据分配了固定内存,为设备数据分配了内存:

cudaMallocHost(&hostData, dataSize * sizeof(MyDataType));
cudaMalloc(&deviceData, dataSize * (MyDataType));

然后我处理这些数据。每个时间步我将数据上传到 CUDA,处理数据并从 CUDA 下载数据:

cudaMemcpy(deviceData, hostData, dataSize * sizeof(MyDataType), cudaMemcpyHostToDevice);

//processing data

cudaMemcpy(hostData, deviceData, dataSize * sizeof(MyDataType), cudaMemcpyDeviceToHost);

但是这个过程太慢了。将数据复制到 CUDA 大约需要所有工作时间的 3-5%。从 CUDA 复制数据大约需要 80-85% 的工作时间。

如何减少数据传输时间?

【问题讨论】:

  • 对我来说,了解您正在使用的数据类型很重要。您可以创建自定义结构来存储数据,可以使用全局内存来存储结果,当内存不足时,将结果保存到硬盘。您是否会通过计算最大限度地利用 GPU?
  • @semm0 我的数据类型由一些 float3 和 float 值组成。我实现了流体模型(如 SPH)。我使用每个计算步骤的结果来渲染我的粒子。
  • 你真的确定你正在正确地计时和解释你的代码的计时吗? cudaMemcpy 是一个阻塞调用,但内核启动是异步的。如果您没有正确执行此操作,那么您测量的从 GPU 复制的时间实际上可能包括先前内核的执行时间
  • @talonmies 我希望我做的一切都是正确的。我使用此代码进行基准测试:my code
  • cudaThreadSynchronize() 已弃用,不应使用。 cudaDeviceSynchronize() 是自 CUDA 4.0 发布以来使用的正确 API。但是,是的,如果您想从主机以这种方式测量时间,则需要使用同步。您还可以使用来自 CUDA 分析工具之一的 API 跟踪

标签: c++ cuda


【解决方案1】:

事实证明,这是一个时间问题和内核启动的异步特性,而不是数据传输速度慢。定时设备到主机传输包括执行先前的内核,因为cudaMemcpy 调用是内核启动序列后的第一个阻塞调用。我们没有在问题中看到任何实质的代码,但解决方案是更改这种类型的 API 调用序列:

cudaMemcpy(deviceData, hostData, dataSize * sizeof(MyDataType), cudaMemcpyHostToDevice);

//processing data by launching kernels

cudaMemcpy(hostData, deviceData, dataSize * sizeof(MyDataType), cudaMemcpyDeviceToHost);

到这里:

cudaMemcpy(deviceData, hostData, dataSize * sizeof(MyDataType), cudaMemcpyHostToDevice);

//processing data by launching kernels

cudaDeviceSynchronize(); // host code blocks here instead
cudaMemcpy(hostData, deviceData, dataSize * sizeof(MyDataType), cudaMemcpyDeviceToHost);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多