我有一个向量vector<vector<double>> data
的向量。
我想只复制那个“2D矩阵”中包含的信息,因为CUDA中没有向量。
所以我使用的第一种方法是
vector<vector<double>> *values;
vector<vector<double>>::iterator it;
double *d_values;
double *dst;
checkCudaErr(
cudaMalloc((void**)&d_values, sizeof(double)*M*N)
);
dst = d_values;
for (it = values->begin(); it != values->end(); ++it){
double *src = &((*it)[0]);
size_t s = it->size();
checkCudaErr(
cudaMemcpy(dst, src, sizeof(double)*s, cudaMemcpyHostToDevice)
);
dst += s;
}
使用NVVP进行分析后,我获得了非常低的cudaMempcpy吞吐量。我认为这是逻辑,因为我发送的数量非常少 每个cudaMemcpy调用中的字节数。 所以我决定改变一点代码来尝试改进这个,所以第二种方法是
double *h_values = new double[M*N];
dst = h_values;
for (it = values->begin(); it != values->end(); ++it){
double *src = &((*it)[0]);
size_t s = it->size();
memcpy(dst, src, sizeof(double)*s);
dst += s;
}
checkCudaErr(
cudaMemcpy(d_values, h_values, sizeof(double)*M*N, cudaMemcpyHostToDevice)
);
分析后的结果仍然是低memcpy吞吐量。 所以,我的问题是,如何从主机到设备改进副本?
我正在使用Quadro K4000。第一个案例我得到25 MB / s,第二个案例得到2 GB / s。 M = 5且N = 2000000.我必须说M的值是一个常见值,但有时它可以达到50。
答案 0 :(得分:4)
吞吐量较慢的原因可能是您使用new分配双矩阵。此内存未锁定页面。您可以使用系统功能(不知道您使用的系统)或提供此功能的cuda功能。它将是cudaMallocHost
。
只需删除=new double[M*N]
,然后将h_values
设置为cudaMallocHost(&h_values, sizeof(double)*M*N)
(当然不要删除它,但要将其释放(使用cudaFreeHost
))。
顺便说一下。理论最高速度为8 GB / s(PCI 2.0 x 16通道),实际上你将保持低于它(约6 GB / s)。