__syncthreads()之间是否有任何阻止写入后写入内部共享内存的危险?

时间:2017-04-20 12:21:09

标签: cuda synchronization memory-barriers gpu-shared-memory hazard

我有一个warp,它将一些数据写入共享内存 - 没有覆盖,很快就从共享内存中读取。虽然我的块中可能还有其他扭曲,但它们不会触及共享内存的任何部分,也不会写入我感兴趣的扭曲读取的任何地方。

现在,我记得尽管warps以锁步方式执行,但我们无法保证共享内存写入之后的共享内存读取将返回warp之前所谓的相应值。 (理论上这可能是由于指令重新排序或 - 正如@RobertCrovella指出的那样 - 编译器优化了共享内存访问)

因此,我们需要采用一些显式同步。显然,块级__syncthreads()起作用。这就是does

  

__syncthreads()用于协调同一块的线程之间的通信。当块中的某些线程访问共享或全局内存中的相同地址时,对于某些内存访问,可能存在写后读,写后读或写后写危险。通过同步这些访问之间的线程可以避免这些数据危险。

这对我的需求来说太强大了:

  • 它也适用于全球内存,而不仅仅是共享内存。
  • 执行 inter-warp 同步;我只需要内部经纱
  • 它可以防止所有类型的危险 R-after-W,W-after-R,W-after-W ;我只需要 R-after-W
  • 它也适用于多个线程执行写入共享内存中相同位置的情况;在我的情况下所有共享内存写入都是不相交的

另一方面,__threadfence_block() does not seem to suffice之类的东西。有什么"介于两者之间"那两个层次的力量?

注意:

  • 相关问题:CUDA __syncthreads() usage within a warp
  • 如果您打算建议我使用改组,那么,是的,有时可能 - 但是如果您想要对数据进行数组访问,即动态决定共享的哪个元素则不行您要阅读的数据。这可能会泄漏到当地的记忆中,这对我来说似乎很可怕。
  • 我想也许volatile可能对我有用,但我不确定使用它会不会做我想要的。
  • 如果您的答案假设计算机功能至少为XX.YY,那就足够了。

1 个答案:

答案 0 :(得分:1)

如果我正确理解@RobertCrovella,这段代码应该是安全的:

/* ... */
volatile MyType* ptr = get_some_shared_mem();
ptr[lane::index()] = foo();
auto other_lane_index = bar(); // returns a value within 0..31
auto other_lane_value = ptr[other_lane_index];
/* ... */

因为volatile的使用。 (并假设bar()不会混乱引入自己的危险。)