Cuda易失性变量是否需要Threadfence?

Cuda易失性变量是否需要Threadfence?,cuda,Cuda,Volatile force每个共享/全局内存写入/读取直接进入共享/全局内存。这会自动完成threadfenced的功能吗?例如: volatile __shared__ int s; s = 2; s = 10 那么“s=2”和“s=10”之间不需要螺纹围栏 我们是否可以说,对于易失性变量,不需要threadfence?如果没有,共享内存中易失性变量的定义如下: volatile __shared__ int s; 执行以下行后threadblock中其他线程的任何访问: s = 2;

Volatile force每个共享/全局内存写入/读取直接进入共享/全局内存。这会自动完成threadfenced的功能吗?例如:

volatile __shared__ int s;

s = 2;
s = 10
那么“s=2”和“s=10”之间不需要螺纹围栏


我们是否可以说,对于易失性变量,不需要threadfence?如果没有,共享内存中易失性变量的定义如下:

volatile __shared__ int s;
执行以下行后threadblock中其他线程的任何访问:

s = 2;
将看到
s
包含2,假设
s
没有进一步更新。但是,
volatile
不会造成任何障碍<代码>\uu threadfence()是执行障碍。在保证其他线程可以看到对共享内存和全局内存(对于
\uuu threadfence()
)的更新之前,所讨论的线程不会超出该障碍

但是,按照以下顺序:

s = 2;
s = 10;

无法保证其他线程将看到什么(除了在warp synchronous情况下,并且取决于您没有提供的进一步场景描述),除了它们将看到2或10(同样,假设
s
没有进一步的更新)。

编程指南中记录了这两个概念。你看过文件了吗?为什么在s=2和s=10之间需要一个螺纹围栏?只有在另一个线程中发生了其他事情,这才有关系。和你的
volatile s定义似乎具有线程本地作用域。您的问题中提出的方案不完整,您的问题也不清楚。
volatile
控制线程内的访问行为<代码>\uu threadfence()
提供线程之间的同步。当前线程将暂停,直到其他线程可以看到对共享/全局内存的所有写入。因此,使用
volatile
限定符不能代替使用
\uuu threadfence()
.Rober,本文档分别描述volatile和threadfence的行为。我试着比较这两种方法,找出在什么情况下应该使用哪一种。我将该变量更改为共享内存中的变量。njuffa,是的,volatile不指定其他线程的行为。如果线程更新共享/全局变量,新值将直接进入共享/全局内存。这是否意味着更新后对共享/全局内存的任何访问都将获得threadfence要求的正确值?例如,在设置“s=2”之后,即使没有调用threadfence,其他线程对s的任何访问都会得到值2。这就是我所担心的。根据volatile变量的描述,“s=2”将更新共享/全局变量中的变量s。现在,如果任何其他线程读/写s,也将进入内存以获取变量s的值2。赋值“s=10”后,s的任何其他访问将获得值10。我能想到的唯一一件事是,编译器对这两个赋值进行了重新排序。我同意volatile确实会造成障碍,而threadfence会造成障碍。但是,如果保证了同一可变变量的不同更新顺序,那么屏障对我来说就没有用处了,因为threadfence除了保证更新顺序外,也不保证其他线程什么时候可以看到更新。编译器无法对这两个赋值重新排序,因为重新排序后的最终结果是不同的。@YangLiu
volatile
,与内存障碍相反,并不保证存储在全局或共享内存中的值。它只是防止编译器对该变量进行任何类型的优化(没有重新排序、没有常量传播、没有死代码消除、没有在可能的情况下在寄存器中缓存值等等)。另一方面,内存障碍要求处理器将对变量所做的所有更改实际提交到底层存储,并使这些更改对世界其他地方可见。这两个概念是正交的。根据编程指南“如果位于全局或共享内存中的变量被声明为易失性变量,编译器会假定它的值可以随时被另一个线程更改或使用,因此对该变量的任何引用都会编译为实际的内存读或写指令”,似乎易失性变量的更新实际上会对内存进行更改。我错了吗?