欢迎光临散文网 会员登陆 & 注册

CUDA内存栅栏(Memory Fence)理解

2022-09-22 11:12 作者:不会跑路的小向晚  | 我要投稿

CUDA中文教材的翻译太晦涩了,英文文档也全都是长难句,导致内存栅栏非常难理解。在本文中我会重新梳理一遍自己的理解,并用实验验证。

让我们在全局内存中初始化两个变量:

然后在线程 i 中修改这两个变量:

从线程 i 的视角来看,变量X的写入在变量Y的写入之前,这看似是对的,但编译器会发现X和Y之间没有依赖关系,然后把它们优化成并行写入,所以此时如果用另一个并行的线程读取X和Y变量,X在Y之前写入的这个顺序就无法保证。读取操作也是如此,顺序无法得到保障。

读取变量:

假设write和read函数分别由并行的线程 i 和线程 j 运行,此时打印出来可能有四种结果:

    A=1, B=2 ;   说明 j 在 i 之前读取了变量,可以接受

    A=10, B=20;说明 i 在 j 之前写入了变量,可以接受

    A=10, B=2;  说明 i 已经写入A,但没来得及写入B,j 已经读取了变量,可以接受

    A=1, B=20;     说明 i 写入顺序被并行化,而B写在了A前面,这是不能接受的情况,因为它可能会误导其他线程

为了避免第四种情况的出现,需要用内存栅栏函数,来保证线程 i 的读写顺序从线程 j 的视角来看不会颠倒。完整代码如下:

我们改变一下线程配置,就能出现不同的结果:

无论线程配置如何改动,都只会出现前三种可以接受的情况,而第四种情况是不可能出现的,因为内存栅栏__threadfence保证了读写顺序。

新版的内存栅栏函数似乎改名了(cuda::atomic_thread_fence),旧版的函数名可能会在未来被弃用。

CUDA内存栅栏(Memory Fence)理解的评论 (共 条)

分享到微博请遵守国家法律