CUDA关键部分,线程/扭曲执行模型和NVCC编译器决策

时间:2019-01-05 21:06:13

标签: compilation cuda compiler-optimization critical-section gpu-atomics

最近我发布了此question的一个关键部分。这是类似的question。在这些问题中,给定的答案是说,because the order of the various paths of execution is up to the compiler是否取决于代码,取决于编译器。

要详细说明其余问题,我需要以下摘录自The CUDA programming guide

  
      
  1. ...组成扭曲的各个线程从同一程序地址一起开始,但是它们具有自己的指令地址计数器和寄存器状态,因此可以自由分支和独立执行。...
  2.   
  3. warp一次执行一条通用指令,因此,当warp的所有32个线程都同意它们的执行路径时,就可以实现充分的效率。如果warp的线程通过依赖于数据的条件分支发散,那么warp会串行执行所采用的每个分支路径,从而禁用不在该路径上的线程,并且当所有路径完成时,这些线程会收敛回到同一执行路径... 。
  4.   
  5. 在扭曲的整个生命周期中,多处理器处理的每个扭曲的执行上下文(程序计数器,寄存器等)都在芯片上维护。因此,从一个执行上下文切换到另一个执行上下文是没有代价的,并且在每个指令发布时间,warp调度程序都会选择一个具有准备好执行下一条指令的线程(warp的活动线程)的warp,然后将指令发布给那些线程。
  6.   

从这三个摘录中我了解到,线程可以与其余线程自由地分开,如果线程之间存在分歧,则所有分支的可能性将被序列化;如果采取分支,它将执行直到完成。这就是为什么上面提到的问题以死锁结束的原因,因为编译器施加的执行路径的顺序导致采用了没有得到锁的分支。

现在的问题是:编译器不应该总是按用户编写的顺序放置分支吗?是否有高级方法可以强制执行该顺序?我知道,编译器可以优化指令,对指令进行重新排序等,但是编译器不能从根本上改变代码的逻辑(是的,有一些例外,例如某些没有volatile关键字的内存访问,但这就是为什么关键字存在的原因,来将控制权交给用户)。


编辑

这个问题的重点与关键部分无关,而与编译器有关,例如,在第一个链接中,编译标志会极大地改变代码的逻辑。一个“起作用”,而另一个不起作用。令我困扰的是,在所有参考文献中,它都只是要小心一点,而与nvcc编译器的未定义行为无关。

1 个答案:

答案 0 :(得分:1)

我相信CUDA编译器不会设置或保证执行顺序。据我所记得,这是设置它的硬件。

因此

  

编译器不应该总是按用户编写的顺序放置分支吗?

它仍然不能控制执行顺序

  

是否有高级方法可以执行该命令?

synchronization instructions就像__syncthreads()

  

编译器...不应从根本上改变代码的逻辑

CUDA代码的语义与C ++代码的语义不同... if分支的顺序执行不是语义的一部分。

我知道这个答案可能不会令您满意,但这就是事情的好坏所在。