【发布时间】:2011-12-20 19:15:07
【问题描述】:
我目前正在阅读http://code.google.com/p/stanford-cs193g-sp2010/ 上的教程示例来学习 CUDA。下面给出了演示__global__ 函数的代码。它只是创建了两个数组,一个在 CPU 上,一个在 GPU 上,用数字 7 填充 GPU 数组并将 GPU 数组数据复制到 CPU 数组中。
#include <stdlib.h>
#include <stdio.h>
__global__ void kernel(int *array)
{
int index = blockIdx.x * blockDim.x + threadIdx.x;
array[index] = 7;
}
int main(void)
{
int num_elements = 256;
int num_bytes = num_elements * sizeof(int);
// pointers to host & device arrays
int *device_array = 0;
int *host_array = 0;
// malloc a host array
host_array = (int*)malloc(num_bytes);
// cudaMalloc a device array
cudaMalloc((void**)&device_array, num_bytes);
int block_size = 128;
int grid_size = num_elements / block_size;
kernel<<<grid_size,block_size>>>(device_array);
// download and inspect the result on the host:
cudaMemcpy(host_array, device_array, num_bytes, cudaMemcpyDeviceToHost);
// print out the result element by element
for(int i=0; i < num_elements; ++i)
{
printf("%d ", host_array[i]);
}
// deallocate memory
free(host_array);
cudaFree(device_array);
}
我的问题是为什么他们用双指针措辞cudaMalloc((void**)&device_array, num_bytes); 语句?甚至 here 上 cudamalloc() 的定义说第一个参数是一个双指针。
为什么不像malloc函数在CPU上那样简单地返回一个指向GPU上分配内存开始的指针?
【问题讨论】:
-
因为它会返回一个错误代码,告诉您失败的原因。在失败时返回空指针,如 malloc(),是错误代码的不良替代品,仅表示“它不起作用”。你应该检查一下。
-
@Hans:这仍然是一个糟糕的 API 设计。相反,它应该使用一个额外的
int *error参数来存储错误代码,当返回值为空指针时该参数有效。照原样,该设计否定了void指针的所有好处,并要求您跳过障碍才能正确使用该功能。 -
@R.:您在批评 API 的同时提供了替代方案 - 大多数 API 批评者都没有提出替代方案 - 但除非您认为每个 CUDA 运行时调用都应该采用额外的 int * 传回错误代码,(这会使 API 更加混乱和难以使用),您的替代提案不是正交的,并且违反了最小惊讶原则。
-
违反最小惊讶原则比要求临时
void *到处都是小得多。当用户不关心原因时,int *error可能为空。实际上,除了“内存不足”之外,我没有看到分配失败的原因(更重要的是,调用者没有理由关心它失败的原因),所以这可能只是一个设计错误。