通常情况下,如果一个块向全局内存中写入了某些内容,另一个块并不能保证“看到”它。此外,在写入全局内存时也没有任何保证,除了发出该写入的块之外。有两个例外:- 原子操作 - 这些始终可以被其他块看到 - threadfence 想象一下,一个块生成了一些数据,然后使用原子操作标记一个标志,表示数据已经存在。但是,其他块在看到标志后仍可能读取不正确或不完整的数据。__threadfence函数来拯救,确保顺序。在它之前的所有写入都真正发生在它之前,在其他块中看到。请注意,__threadfence函数不一定需要阻塞当前线程,直到它对全局内存的写入对网格中的所有其他线程可见为止。以这种天真的方式实现,__threadfence函数可能会严重影响性能。例如,如果您执行以下操作:1. 存储数据 2. __threadfence() 3. 原子标记一个标志则保证如果其他块看到标志,则它也将看到数据。进一步阅读:CUDA编程指南,第B.5章(截至版本11.5)
__syncthreads()
比__threadfence_block()
更强。在__syncthreads()
之后,您可以保证屏障之前的所有共享/全局内存写入对屏障之后的所有线程都是可见的。但是,__syncthreads()
仅对块产生影响,并且不保证不同块的线程之间的任何内容。 - CygnusX1__syncthreads
和__threadfence_block
确保给定块中所有先前的全局更改对该块中的所有线程可见。然而,这通常不是 syncthreads 的常见用例,因为通常你会想要使用共享内存来进行这种类型的线程通信。 - CygnusX1