1.最简单的方法,在同步点退出kernel回到host端用clfinish同步。再启动kernel继续计算。缺点是开销极大。
2.其次可以用global int变量做计数器,每个到达同步点的线程进行原子加。每个线程再while循环等待计数器达到线程数后再继续运行。这个方法可以进一步用树形分布计数器进行改进,减少原子操作冲突,但依然比较慢。
3.采用无锁的全局同步,将全局同步转化为group或block内部的同步问题。请参加IPDPS 2010的论文:Inter-Block GPU Communication via Fast Barrier Synchronization .http://synergy.cs.vt.edu/pubs/papers/xiao-ipdps2010-gpusync.pdf
可以考虑使用mem_fence接口。这个是对存储器事务进行同步的。
Orders loads and stores of a work-item executing a kernel. This means that loads and stores preceding the mem_fence will be committed to memory before any loads and stores following the mem_fence.
如果你真的要做到global的线程执行同步,那么可以考虑barrier与原子操作相结合进行解决。当然,对全局work-item进行同步的代价相对而言还是比较高昂的。