Я использую Windows 7 64 бит, CUDA 4.2, Visual Studio 2010.
Сначала я запускаю некоторый код на cuda, затем загружаю данные обратно на хост. Затем выполните некоторую обработку и вернитесь к устройству.
Затем я сделал следующую копию с устройства на хост, он работает очень быстро, как 1 мс.
clock_t start, end;
count=1000000;
thrust::host_vector <int> h_a(count);
thrust::device_vector <int> d_b(count,0);
int *d_bPtr = thrust::raw_pointer_cast(&d_b[0]);
start=clock();
thrust::copy(d_b.begin(), d_b.end(), h_a.begin());
end=clock();
cout<<"Time Spent:"<<end-start<<endl;
Требуется ~ 1 мс, чтобы закончить.
Затем я снова запустил какой-то другой код на cuda, в основном атомарные операции. Затем я копирую данные с устройства на хост, это занимает очень много времени, например ~ 9 с.
__global__ void dosomething(int *d_bPtr)
{
....
atomicExch(d_bPtr,c)
....
}
start=clock();
thrust::copy(d_b.begin(), d_b.end(), h_a.begin());
end=clock();
cout<<"Time Spent:"<<end-start<<endl;
~ 9 с
Я запускал код несколько раз, например
int i=0;
while (i<10)
{
clock_t start, end;
count=1000000;
thrust::host_vector <int> h_a(count);
thrust::device_vector <int> d_b(count,0);
int *d_bPtr = thrust::raw_pointer_cast(&d_b[0]);
start=clock();
thrust::copy(d_b.begin(), d_b.end(), h_a.begin());
end=clock();
cout<<"Time Spent:"<<end-start<<endl;
__global__ void dosomething(int *d_bPtr)
{
....
atomicExch(d_bPtr,c)
....
}
start=clock();
thrust::copy(d_b.begin(), d_b.end(), h_a.begin());
end=clock();
cout<<"Time Spent:"<<end-start<<endl;
i++
}
Результаты практически одинаковы.
В чем может быть проблема?
Спасибо!
Проблема заключается в синхронизации, а не в изменении производительности копирования. Запуски ядра являются асинхронными в CUDA, поэтому то, что вы измеряете, это не просто время для thrust::copy
но и для предыдущего ядра, которое вы запустили для завершения. Если вы измените свой код для синхронизации операции копирования на что-то вроде этого:
cudaDeviceSynchronize(); // wait until prior kernel is finished
start=clock();
thrust::copy(d_b.begin(), d_b.end(), h_a.begin());
end=clock();
cout<<"Time Spent:"<<end-start<<endl;
Вы должны найти, что время переноса восстановлено до их предыдущей производительности. Таким образом, вы действительно не «почему это thrust::copy
медленно «, это» почему мое ядро медленно «. И на основе довольно ужасного псевдокода, который вы разместили, ответ» потому что он полон atomicExch()
вызовы, которые сериализуют транзакции памяти ядра «.
Я предлагаю вам использовать cudpp, на мой взгляд, это быстрее, чем тяга (я пишу магистерскую диссертацию по оптимизации, и я попробовал обе библиотеки). Если копирование происходит очень медленно, вы можете попробовать написать собственное ядро для копирования данных.