[英]How can I pass a C++ array of structs to a CUDA device?
我花了两天的时间试图解决这个问题并且无处可去。 假设我有一个看起来像这样的结构:
struct Thing {
bool is_solid;
double matrix[9];
}
我想创建一个名为things
结构数组,然后在GPU上处理该数组。 就像是:
Thing *things;
int num_of_things = 100;
cudaMallocManaged((void **)&things, num_of_things * sizeof(Thing));
// Something missing here? Malloc individual structs? Everything I try doesn't work.
things[10].is_solid = true; // Segfaults
以这种方式执行此操作是否是最佳实践,而不是使用num_of_things
较大的数组传递单个结构? 在我看来,可能会变得非常讨厌,尤其是当你已经有阵列时(比如matrix
,需要9 * num_of_things
。
任何信息将不胜感激!
在评论中的一些对话框之后,似乎OP发布的代码没有问题。 我能够成功编译并运行围绕该代码构建的测试用例,OP也是如此:
$ cat t1005.cu
#include <iostream>
struct Thing {
bool is_solid;
double matrix[9];
};
int main(){
Thing *things;
int num_of_things = 100;
cudaError_t ret = cudaMallocManaged((void **)&things, num_of_things * sizeof(Thing));
if (ret != cudaSuccess) {
std::cout << cudaGetErrorString(ret) << std::endl;
return 1;}
else {
things[10].is_solid = true;
std::cout << "Success!" << std::endl;
return 0;}
}
$ nvcc -arch=sm_30 -o t1005 t1005.cu
$ ./t1005
Success!
$
关于这个问题:
以这种方式执行此操作是否是最佳实践,而不是使用num_of_things较大的数组传递单个结构?
是的,这是一种明智的做法,无论是否使用托管内存,都可以使用。 可以使用单个cudaMemcpy
调用以简单的方式将一个或多或少任何不包含嵌入式指针的结构数组转移到GPU(例如,如果未使用托管内存)。
要解决有关cudaMallocManaged
的3rd( flags
)参数的问题:
cudaMemAttachGlobal
的默认参数。 这可以通过查看cuda_runtime.h
文件来确认,或者只是编译/运行上面的测试代码。 这个特殊点似乎是对文档的疏忽,我在NVIDIA上提出了一个内部问题来看一看。 因此,文档可能会在未来发生变化。 最后,在您遇到CUDA代码时遇到问题时,总是按顺序进行正确的cuda错误检查 ,并且使用这些错误检查可能会对所发生的任何错误有所了解。 OP在代码注释中报告的seg错误几乎肯定是由于cudaMallocManaged
调用失败(可能是因为错误地提供了零参数),因此有问题的指针( things
)没有实际分配。 随后使用该指针将导致seg错误。 我的测试代码演示了如何避免seg故障,即使cudaMallocManaged
调用由于某种原因失败,并且密钥是正确的错误检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.