内存复制吞吐量低主机到设备

时间:2013-07-17 07:56:46

标签: cuda gpgpu

我有一个向量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。

1 个答案:

答案 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)。