并发写入相同的全局内存位置

lin*_*ina 16 c c++ cuda

我有几个块,每个块都有一个大小为512的共享内存数组中的整数.如何检查每个块中的数组是否包含零作为元素?

我正在做的是创建一个驻留在全局内存中的数组.此数组的大小取决于块的数量,并初始化为0.因此,a[blockid] = 1如果共享内存数组包含零,则每个块都会写入.

我的问题是当我在一个块中同时写几个线程时.也就是说,如果共享内存中的数组包含多个零,则会写入多个线程a[blockid] = 1.这会产生任何问题吗?

换句话说,如果2个线程将完全相同的值写入全局内存中完全相同的数组元素,那会不会有问题?

Tom*_*Tom 19

对于CUDA程序,如果在经写入到同一位置的多个线程,则位置被更新,但它是不确定的 多少倍的位置被更新(即实际写入多少发生在系列),它是不确定的 ,其线程将写最后一次(即哪个线程将赢得比赛).

对于计算能力为2.x的设备,如果warp中的多个线程写入同一地址,则只有一个线程实际执行写操作,线程未定义.

CUDA C编程指南第F.4.2节:

如果由warp执行的非原子指令写入warp的多个线程的全局内存中的相同位置,则只有一个线程执行写操作,而哪个线程执行它是未定义的.

有关详细信息,另请参阅指南的第4.1节.

换句话说,如果写入给定位置的所有线程都写入相同的值,那么它是安全的.


tal*_*ies 13

在CUDA执行模型中,无法保证从同一块中的线程到同一全局内存位置的每个同时写入都将成功.至少有一个写操作可以工作,但编程模型不能保证将发生多少写事务,或者如果执行多个事务,它们将以何种顺序发生.

如果这是一个问题,那么更好的方法(从正确的角度来看),就是每个块只有一个线程进行全局写操作.您可以使用原子设置的共享内存标志或还原操作来确定是否应设置该值.您选择哪个可能取决于可能存在多少个零.零越多,减少的吸引力就越大.CUDA包括warp级别__any()__all()运算符,可以在几行代码中构建一个非常有效的布尔减少.

  • 有关详细信息,请参阅我的答案(不能在评论中发布链接和引号!).CUDA确实确保如果warp中的多个线程写入同一位置,那么至少一个线程将成功写入该位置,但是哪个线程(或哪个线程最后一个)是未定义的. (6认同)