1

我正在使用 CUDA,但似乎我无法将 STL 向量作为参数传递,所以我需要将这些向量矩阵转换为动态数组。

std::vector< std::vector<float> > some_matrix;float **f;

我尝试使用 memcpy 函数,但由于某种原因它不能按预期工作,如果我尝试复制内容,原始矩阵中的一些值会被更改为垃圾。我避免使用 for 循环,因为这会降低效率。

4

1 回答 1

2

正如您所发现的,不可能将 a 传递std::vector给 CUDA 内核并在内核代码中使用它,也不可能将您可能从 a 构造的简单主机指针数组传递std::vector< std::vector<float> >给 CUDA 内核.

您需要做的是首先创建一个设备指针的主机数组(因此您复制到设备的每一行都有一个条目)并将该指针数组复制到设备。这意味着您需要对复制到设备的每个矩阵行或列进行 cudaMalloc 和 cudaMemcpy 调用。你可以这样做:

std::vector< std::vector<float> > some_matrix;

float** f = new float*[some_matrix.size()];
for (int i = 0; i < some_matrix.size(); ++i) {
    size_t szp = sizeof(float) * some_matrix[i].size();
    float* p;
    cudaMalloc((void **)&p, sz);
    cudaMemcpy(p, &some_matrix[i][0], szp, cudaMemcpyHostToDevice);
    f[i] = p;
}

float** f_dev;
size_t szf =  sizeof(float*) * some_matrix.size();
cudaMalloc((void **)&f_dev, szf);
cudaMemcpy(f_dev, f, szf, cudaMemcpyHostToDevice);

[免责声明:用浏览器编写,从未编译或测试,使用风险自负]

之后f_dev可以安全地传递给 CUDA 内核并在设备上使用。

希望您可以从上面的代码中看出为什么这种数据结构在 GPU 上不是很容易使用。设置和传输它有很多 API 开销,然后在设备上,由于将值获取到内存所需的双指针间接,您会遇到延迟损失。

对于源数据不是“锯齿状数组”(即矩阵中的所有行长度相同)的情况,存储在线性内存中的扁平列主数组或行主数组是更好的解决方案。如果源数组是锯齿状的,请考虑使用类似于 CSR 或 CSC 稀疏矩阵格式的结构。这些并没有在设备上提供太多的性能改进,但它们确实减少了管理它们的主机端 API 开销。

于 2013-10-03T06:16:57.487 回答