关于CUDA记忆的问题

时间:2015-12-09 11:01:08

标签: memory cuda gpgpu

我对CUDA编程很陌生,有一些关于内存模型的东西对我来说还不太清楚。比如,它是如何工作的?例如,如果我有一个简单的内核

__global__ void kernel(const int* a, int* b){ 
    some computation where different threads in different blocks might      
    write at the same index of b
}

所以我想a将在所谓的常量记忆中。但是b呢?由于不同块中的不同线程会写入其中,它将如何工作?我在某处读到,保证在同一块中不同线程的全局内存中并发写入的情况下,至少会写入一个,但不保证其他线程。我是否需要担心这一点,例如,如果一个块中的每个线程都在共享内存中写入,一旦它们全部完成,是否有一个写入全局内存?或者CUDA是否为我照顾它?

1 个答案:

答案 0 :(得分:2)

  

所以我想a将在所谓的常量记忆中。

是的,a 指针将在常量内存中,但不是因为它标记为const(这是完全正交的)。 b 指针也在常量内存中。 所有内核参数都在常量内存中传递(CC 1.x除外)。从理论上讲,ab指向的内存可以是任何东西(设备全局内存,主机固定内存,UVA可以寻址的任何东西,我相信)。它所在的位置由您,用户选择。

  

我在某处读到,保证在同一块中不同线程的全局内存中并发写入的情况下,至少会编写一个,但是不保证其他线程。

假设您的代码如下:

b[0] = 10; // Executed by all threads

然后是的,那是一个(良性)竞争条件,因为所有线程都将相同的值写入同一位置。写入的结果是定义的,但是写入的数量是未指定的,并且执行" final"的线程也是如此。写。唯一的保证是至少发生一次写操作。在实践中,我相信每个warp会发出一次写入,如果你的块包含多个warp(他们应该这样做),这会浪费带宽。

另一方面,如果您的代码如下所示:

b[0] = threadIdx.x;

这是明确的未定义行为。

  

我是否需要担心这一点,即例如让一个块中的每个线程都写入共享内存,一旦完成它们,是否有一个写入全局内存?

是的,通常是这样做的。