如何实现表单
的繁忙旋转机制while(variable == 0);
在某个事件发生后,其他CUDA线程将变量更新为1。
我试着像上面那样编写它,但代码似乎被忽略了,调用线程只是运行它而没有等待。我绝对确定该值为0,但线程根本不会等待。 另外,如果我写:
while(variable == 0) __threadfence();
为了不存在变量缓存的风险,即使变量最终设置为1,线程也会无限期地阻塞。 这对我来说都是非常奇怪的行为,因为在CPU上复制这些代码会产生正确的行为。
编辑:奇怪的是,如果我每个块有1个线程,这似乎可以正常工作,但如果我在一个块中有多个线程则不行。因此,来自一个块的线程可以看到来自其他块的线程完成的写入,但不能查看来自同一块的线程完成的写入。奇怪...
答案 0 :(得分:8)
繁忙的纺纱需要很多关注,你必须非常小心!
你必须记住,32个线程,形成一个完美同步的扭曲工作。如果遇到分支,则不执行分支的线程将被禁用,直到线程执行分支 - 从中退出。 这就是为什么尝试在warp中忙碌旋转会导致死锁:31个线程将永远等待单个禁用线程执行其工作。
其次,如果尝试在块之间进行同步,则必须知道两个块并行运行。从理论上讲,您不知道有多少块正在运行;实际上,您可以阅读GPU的规格,并尽可能多地启动(驱动程序和/或硬件中存在一些错误,这也可能导致一些问题)
第三,你必须记住CUDA编译器试图优化。您必须将共享或全局变量设置为“volatile”以确保始终正在读取它。