我对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是否为我照顾它?
答案 0 :(得分:2)
所以我想
a
将在所谓的常量记忆中。
是的,a
指针将在常量内存中,但不是因为它标记为const
(这是完全正交的)。 b
指针也在常量内存中。 所有内核参数都在常量内存中传递(CC 1.x除外)。从理论上讲,a
和b
指向的内存可以是任何东西(设备全局内存,主机固定内存,UVA可以寻址的任何东西,我相信)。它所在的位置由您,用户选择。
我在某处读到,保证在同一块中不同线程的全局内存中并发写入的情况下,至少会编写一个,但是不保证其他线程。
假设您的代码如下:
b[0] = 10; // Executed by all threads
然后是的,那是一个(良性)竞争条件,因为所有线程都将相同的值写入同一位置。写入的结果是定义的,但是写入的数量是未指定的,并且执行" final"的线程也是如此。写。唯一的保证是至少发生一次写操作。在实践中,我相信每个warp会发出一次写入,如果你的块包含多个warp(他们应该这样做),这会浪费带宽。
另一方面,如果您的代码如下所示:
b[0] = threadIdx.x;
这是明确的未定义行为。
我是否需要担心这一点,即例如让一个块中的每个线程都写入共享内存,一旦完成它们,是否有一个写入全局内存?
是的,通常是这样做的。