2012-10-09 90 views
2

我运行Windows 7 64位,CUDA 4.2,Visual Studio 2010中CUDA设备到主机复制很慢

首先,我运行CUDA一些代码,然后下载数据传回主机。然后做一些处理并返回到设备。 然后我做了以下从设备到主机的副本,它运行速度非常快,如1ms。

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; 

完成需要〜1ms。

然后我又在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; 

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

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

谢谢!

+0

我还是不明白你怎么能''推力:: raw_ptr_cast'与'device_vector'第一个index.I我试图从你的代码运行一个片段,我得到了'错误:类模板的参数列表“推力:: device_ptr“missing missing”error ... – Recker

+0

对不起,我的坏。它应该是int * device_ptr = thrust :: raw_pointer_cast(&d_b [0]);我会更新它。你认为这是造成问题吗?或者我应该直接使用d_b.begin()作为原子操作的输入吗?谢谢! – UserKiwi

+0

你可以发布你能想出的最短重现器吗?我试着从你的代码中做一个简单的例子,但没有看到任何错误。代码中有各种奇怪的语法错误,所以它有助于创建可编译的复制器。 –

回答

8

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

+0

谢谢talonmies !!我会按照你的建议,明天再次运行代码来看看。对不起,可怕的伪代码。我是新来的cuda,我现在没有我的源代码可用...非常感谢! – UserKiwi

+0

我今天测试,talonmies是完全正确的!一切都和他所描述的一样!非常感谢你! – UserKiwi

+0

@UserKiwi:如果这回答了你的问题,那么也许你会这样[接受它](http://meta.stackexchange.com/a/5235/163653)。这标志着问题已经完成。 – talonmies

0

我建议你使用cudpp,在我看来比推力更快(我在写关于优化的主要论文,并且我尝试了两个库)。如果复制速度非常慢,您可以尝试编写自己的内核来复制数据。

相关问题