为了简化,请说我有这个结构:
someheader.h
typedef struct
{
float x
}someStruct;
在Cuda中,如果C ++应用程序共享结构,设备函数将如何访问结构的成员?
例如:
__global__ void stuff( someStruct *g ) {
g[0].x = 0.4f;
}
这是正确的方法吗?它似乎没有用。
答案 0 :(得分:1)
Struct本身是一个抽象实体,在主机或设备端没有物理表示。
设备端对象的内存布局与主机端的内存布局完全相同(如果这是您真正要求的),因此您可以安全地将大型struct对象从主机复制到设备,反之亦然。
访问对象的成员只不过是在编译时计算正确的偏移量并在运行时将其添加到对象指针(this
)。 CUDA完全有能力做到这一点。
someStruct.x=2
将在汇编语言中转换为类似的内容:
mov [someStruct]+0, 2
其中0
是结构中成员x
的偏移量。
<强>更新强>
主机和设备内存是完全独立的(一个在你的RAM中,另一个在你的GPU上)。没有什么是共享的,一切都必须来回发送(这可能非常耗时)。使用CudaMemcpy功能复制数据。
答案 1 :(得分:1)
您需要将结构数组传输到GPU。
例如,要访问内核中的浮点数组,您需要执行以下操作
__global__ static void myKernel(float *val)
{
val[0] = 0.4f;
}
int main()
{
...
cudaMemcpy(d_Val, h_Val, n * sizeof(float), cudaMemcpyHostToDevice);
...
}
这当然是基础知识。您可以使用任何数据类型替换float并获得相同的行为。结构只是用户定义的数据类型。
这与发送单个float(因此是单个结构)不同,因为内核的所有输入都在GPU可以访问的运行时(取决于卡)被推送到GPU内存系统的某个部分这些价值观。因此,如果输入是结构,则当内核尝试访问它时,整个结构驻留在GPU上。但是,如果您发送指向主机上生成的结构的指针,则GPU具有指针值而不是实际数据。