【发布时间】:2016-12-23 00:42:03
【问题描述】:
我遵循了this question 和this link 提供的指导,它们处理了将指针数组传递给设备并返回的概念,但是当指针指向对象时,我似乎在处理我的具体情况。请参阅下面的示例代码,为简洁起见,我删除了错误检查。
// Kernel
__global__ void myKernel(Obj** d_array_of_objs)
{
// Change the scalar of each object to 5
// by dereferencing device array to get
// appropriate object pointer.
*d_array_of_objs->changeToFive(); <--------- SEE QUESTION 4
}
// Entry point
int main()
{
/********************************/
/* INITIALISE OBJ ARRAY ON HOST */
/********************************/
// Array of 3 pointers to Objs
Obj* h_obj[3];
for (int i = 0; i < 3; i++) {
h_obj[i] = new Obj(); // Create
h_obj[i]->scalar = i * 10; // Initialise
}
// Write out
for (int i = 0; i < 3; i++) {
std::cout << h_obj[i]->scalar << std::endl;
}
/**************************************************/
/* CREATE DEVICE VERSIONS AND STORE IN HOST ARRAY */
/**************************************************/
// Create host pointer to array-like storage of device pointers
Obj** h_d_obj = (Obj**)malloc(sizeof(Obj*) * 3); <--------- SEE QUESTION 1
for (int i = 0; i < 3; i++) {
// Allocate space for an Obj and assign
cudaMalloc((void**)&h_d_obj[i], sizeof(Obj));
// Copy the object to the device (only has single scalar field to keep it simple)
cudaMemcpy(h_d_obj[i], &(h_obj[i]), sizeof(Obj), cudaMemcpyHostToDevice);
}
/**************************************************/
/* CREATE DEVICE ARRAY TO PASS POINTERS TO KERNEL */
/**************************************************/
// Create a pointer which will point to device memory
Obj** d_d_obj = nullptr;
// Allocate space for 3 pointers on device at above location
cudaMalloc((void**)&d_d_obj, sizeof(Obj*) * 3);
// Copy the pointers from the host memory to the device array
cudaMemcpy(d_d_obj, h_d_obj, sizeof(Obj*) * 3, cudaMemcpyHostToDevice);
/**********
* After the above, VS2013 shows the memory pointed to by d_d_obj
* to be NULL <------- SEE QUESTION 2.
**********/
// Launch Kernel
myKernel <<<1, 3>>>(d_d_obj);
// Synchronise and pass back to host
cudaDeviceSynchronize();
for (int i = 0; i < 3; i++) {
cudaMemcpy(&(h_obj[i]), h_d_obj[i], sizeof(Obj), cudaMemcpyDeviceToHost); <--------- SEE QUESTION 3
}
// Write out
for (int i = 0; i < 3; i++) {
std::cout << h_obj[i]->scalar << std::endl;
}
return 0;
}
所以问题是:
如果上面
SEE QUESTION 1指示的行为指针分配主机内存,并且一旦我在后续循环中使用cudaMalloc分配设备内存,h_d_obj指向的指针就会被设备地址覆盖,这是否意味着我已经为 3Obj*分配了主机内存,现在没有指针指向它?为什么当我测试返回的状态时
cudaMemcpy成功但显然没有正确复制地址?我期待h_d_obj和d_d_obj的内存地址“数组”相同,因为它们应该指向设备地址空间中的相同Obj。在
SEE QUESTION 3行,假设我在问题2 中是正确的。我还希望能够使用h_d_obj或d_d_obj从设备中检索Obj对象,因为区别仅在于我是否取消引用主机指针以访问指向Obj的设备指针或设备指针,这两者我都可以在cudaMemcpy方法中执行,对吗?如果我使用写入的内容,则复制成功,但h_obj[0]处的指针已损坏,我无法写出数据。在
SEE QUESTION 4行,为什么我不能取消引用Obj**以获取Obj*然后使用->运算符调用device 方法?编译器抱怨它不是指向类类型的指针,事实上它是Obj*告诉我它是。
【问题讨论】:
标签: c++ c arrays pointers cuda