我有一个向量向量vector<vector<double>> data
。我只想复制该“二维矩阵”中包含的信息,因为 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。