【问题标题】:Device -> host vs host -> device copy performance in cuda设备 -> 主机与主机 -> cuda 中的设备复制性能
【发布时间】:2020-08-20 05:35:24
【问题描述】:

我是 CUDA 新手,我的首要任务是实现性能指标。

我注意到,与将数据从设备复制到主机相比,使用推力矢量将数据从主机复制到设备所需的时间更少。谁能解释一下为什么?

int dimension = 1000000; 
thrust::host_vector <int> host_Table (dimension);

tic2=get_time();
thrust::device_vector<int> device_Table =host_Table;
toc2=get_time();

tic3=get_time();
thrust::host_vector<int> host_TableCopiedFromDevice = device_Table;
toc3=get_time();

toc2-tic2 和 toc3-tic3 之间的差异非常大。

谢谢

【问题讨论】:

  • 您能分享差异并计算 Gb/s 指标吗?
  • 这 99% 肯定是时间问题,而不是实际的带宽差异
  • 平台(即您的主板)当然有可能在可分页传输的传输速率上表现出显着差异。大于约 30% 的时序差异可能是由于推力开销(除了复制之外,您在此处执行向量实例化)和/或时序方法错误。如果您想查看快速、一致的传输速率,请使用pinned allocator
  • 欢迎来到 SO! 您的标题格式可能会让用户感到困惑。

标签: cuda thrust


【解决方案1】:

首先,请记住,最好使用Cuda Event API 进行计时测量,而不是使用 CPU 计时器。此外,您可能需要考虑在计时之前进行热身呼叫(有关更多信息,请参阅here)。我认为@Robert Crovella 已经在他的评论中回答了你的问题,提到向量实例化可能是时间差的原因。但为了证明这一点,我做了一个简单的测试,在有和没有向量分配的两种情况下,我测量了设备到主机 (D2H) 和主机到设备 (H2D) 的传输时间。考虑这个基本上等于你的代码的代码:

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <iostream>

int main(){

  int dimension = 1000000; 

  // Some dummy vector to wake up device
  thrust::device_vector<int> dummy_vec (dimension, 1);

  // Create a Cuda event
  cudaEvent_t start, stop;
  cudaEventCreate(&start);
  cudaEventCreate(&stop);
  float elapsed = 0; // time in ms

  thrust::host_vector <int> host_Table (dimension);

  // H2D:
  cudaEventRecord(start);
  thrust::device_vector<int> device_Table = host_Table;  
  cudaEventRecord(stop);
  cudaEventSynchronize(stop);
  cudaEventElapsedTime(&elapsed, start, stop);
  std::cout<<"H2D elapsed time: " << elapsed << " ms"<< std::endl;

  // D2H:        
  cudaEventRecord(start);
  thrust::host_vector<int> host_TableCopiedFromDevice = device_Table;
  cudaEventRecord(stop);
  cudaEventSynchronize(stop);
  cudaEventElapsedTime(&elapsed, start, stop);
  std::cout<<"D2H elapsed time: " << elapsed << " ms"<< std::endl;
}

在 Titan Black(Ubuntu,CUDA 10.1)上运行此程序会给出以下时间值:

H2D elapsed time: 1.76941 ms
D2H elapsed time: 3.80643 ms

你就在这里。 D2H 时间几乎是 H2D 的 2 倍。现在,在传输之前分配了向量的相同代码:

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <iostream>

int main(){

  int dimension = 1000000; 

  // Some dummy vector to wake up device
  thrust::device_vector<int> dummy_vec (dimension, 1);

  // Create a Cuda event
  cudaEvent_t start, stop;
  cudaEventCreate(&start);
  cudaEventCreate(&stop);
  float elapsed = 0; // time in ms

  // initialized vectors
  thrust::host_vector <int> h_vec (dimension, 1);
  thrust::device_vector <int> d_vec (dimension);
  thrust::host_vector <int> h_vec_2 (dimension);

  // H2D:
  cudaEventRecord(start);
  d_vec = h_vec;
  cudaEventRecord(stop);
  cudaEventSynchronize(stop);
  cudaEventElapsedTime(&elapsed, start, stop);
  std::cout<<"H2D elapsed time: " << elapsed << " ms"<< std::endl;

  // D2H:
  cudaEventRecord(start);
  h_vec_2 = d_vec;
  cudaEventRecord(stop);
  cudaEventSynchronize(stop);
  cudaEventElapsedTime(&elapsed, start, stop);
  std::cout<<"D2H elapsed time: " << elapsed << " ms"<< std::endl;

}

给出:

H2D elapsed time: 1.7777 ms
D2H elapsed time: 1.54707 ms

如果我们排除其他因素,这证实了 H2D 和 D2H 内存传输实际上大致相同。另一项可能给您一些提示的调查是将dimension 更改为更小/更大的值,看看它如何改变时差。

【讨论】:

    猜你喜欢
    • 2012-09-29
    • 2023-03-14
    • 2013-09-20
    • 2012-07-14
    • 2017-08-27
    • 1970-01-01
    • 2016-02-09
    • 2013-03-25
    • 1970-01-01
    相关资源
    最近更新 更多