我在下面有一个简单的程序。我的问题是“temp”实际存储在哪里?它在全局内存还是本地内存中?我需要每个 idx 的数组 temp,以便每个线程都有单独的数组 temp。在这种情况下,它工作正常。但是在我的实际程序中,当我尝试从 test2 填充 temp[0] 时,它使程序停止。假设我们有 1024 个线程,那么它只运行大约 200 个线程的内核。所以,我想知道 temp 是否共享。如果是的话,也许那里有碰撞。我也没有收到任何错误消息。请有人解释一下。
__device__ void test2(int temp[], int idx) {
temp[0] = idx;
printf("%d ", temp[0]);
}
__global__ void test() {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int *temp = (int *) malloc(100 * sizeof (int));
test2(temp, idx);
}
int main() {
test << <1, 1024 >> >();
return 0;
}
我的问题是“temp”实际存储在哪里?
分配temp
存储在称为设备堆的地方。它是一种全局内存形式。然而,temp
变量本身(即指针值)在本地内存中 - 其他线程不共享或不可见。
我需要每个 idx 的数组 temp,以便每个线程都有单独的数组 temp。
您会明白这一点,但需遵守以下注意事项。每个线程都有自己的独立数组,由其局部变量引用temp
。每个线程将在设备堆上单独分配存储空间。
人们通常在内核new
或malloc
. 主要原因之一是设备堆最初限制为 8MB,跨越所有设备堆分配。因此,如果有足够多的线程执行一个new
或malloc
多个分配请求,您将耗尽空间。
当空间用完时,API 发出信号的方式是为分配返回零指针值(NULL 指针)。如果您随后尝试使用此 NULL 指针,则会遇到麻烦。
出于调试目的(即证明这种情况正在发生),请== 0
在使用前测试指针是否为 NULL(即)。如果它是 NULL,请不要使用它(也许会打印一条错误消息)。
您可以在文档中或在 SOcuda
标签上的许多问题中阅读有关此内容的更多信息。如果您阅读这些来源中的任何一个,您会发现可以增加设备堆的大小。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句