我正在使用CUDA,但似乎我无法将STL向量作为参数传递,因此我需要将这些向量矩阵转换为动态数组。
std::vector< std::vector<float> > some_matrix;
至float **f;
我试图使用memcpy函数但由于某种原因它没有按预期工作,如果我尝试复制内容,原始矩阵中的一些值被更改为垃圾。 我正在避免使用循环,因为这会降低效率。
答案 0 :(得分:2)
正如您所知,不可能将std::vector
传递给CUDA内核并在内核代码中使用它,并且不可能传递一个简单的主机指针数组。从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开销来管理它们。