4

我正在运行 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 上运行了一些其他代码,主要是原子操作。然后我将数据从设备复制到主机,这需要很长时间,比如~9s。

__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;

~ 9s

我多次运行代码,例如

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++
}

结果几乎相同。
可能是什么问题呢?

谢谢!

4

2 回答 2

10

问题是时间问题之一,而不是复制性能的任何变化。内核启动在 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()序列化内核内存事务的调用”。

于 2012-10-09T05:05:50.640 回答
-1

我建议你使用cudpp,在我看来比推力更快(我正在写关于优化的硕士论文,我尝试了这两个库)。如果拷贝很慢,可以尝试自己写内核拷贝数据。

于 2012-10-09T05:50:14.277 回答