Устройство -> хост против хоста -> производительность копирования устройства в cuda - PullRequest
1 голос
/ 05 мая 2020

Я новичок в CUDA, и моя первая задача - реализовать метрики производительности.

Я заметил, что копирование данных с хоста на устройство с использованием векторов тяги занимает меньше времени по сравнению с копированием данных с устройства на хост. кто-нибудь может объяснить почему?

1 Ответ

1 голос
/ 05 мая 2020

Во-первых, вместо использования таймеров ЦП имейте в виду, что для измерения времени лучше использовать Cuda Event API . Также вы можете подумать о разминке до истечения времени (см. здесь для получения дополнительной информации). Я думаю, что @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 почти в 2 раза больше, чем время 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

  // 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 на меньшее / большее значение и посмотреть, как это изменит разницу во времени.

...