最近我发布了此question的一个关键部分。这是类似的question。在这些问题中,给定的答案是说,because the order of the various paths of execution is up to the compiler是否取决于代码,取决于编译器。
要详细说明其余问题,我需要以下摘录自The CUDA programming guide:
- ...组成扭曲的各个线程从同一程序地址一起开始,但是它们具有自己的指令地址计数器和寄存器状态,因此可以自由分支和独立执行。...
- warp一次执行一条通用指令,因此,当warp的所有32个线程都同意它们的执行路径时,就可以实现充分的效率。如果warp的线程通过依赖于数据的条件分支发散,那么warp会串行执行所采用的每个分支路径,从而禁用不在该路径上的线程,并且当所有路径完成时,这些线程会收敛回到同一执行路径... 。
- 在扭曲的整个生命周期中,多处理器处理的每个扭曲的执行上下文(程序计数器,寄存器等)都在芯片上维护。因此,从一个执行上下文切换到另一个执行上下文是没有代价的,并且在每个指令发布时间,warp调度程序都会选择一个具有准备好执行下一条指令的线程(warp的活动线程)的warp,然后将指令发布给那些线程。
从这三个摘录中我了解到,线程可以与其余线程自由地分开,如果线程之间存在分歧,则所有分支的可能性将被序列化;如果采取分支,它将执行直到完成。这就是为什么上面提到的问题以死锁结束的原因,因为编译器施加的执行路径的顺序导致采用了没有得到锁的分支。
现在的问题是:编译器不应该总是按用户编写的顺序放置分支吗?是否有高级方法可以强制执行该顺序?我知道,编译器可以优化指令,对指令进行重新排序等,但是编译器不能从根本上改变代码的逻辑(是的,有一些例外,例如某些没有volatile关键字的内存访问,但这就是为什么关键字存在的原因,来将控制权交给用户)。
编辑
这个问题的重点与关键部分无关,而与编译器有关,例如,在第一个链接中,编译标志会极大地改变代码的逻辑。一个“起作用”,而另一个不起作用。令我困扰的是,在所有参考文献中,它都只是要小心一点,而与nvcc编译器的未定义行为无关。
答案 0 :(得分:1)
我相信CUDA编译器不会设置或保证执行顺序。据我所记得,这是设置它的硬件。
因此
编译器不应该总是按用户编写的顺序放置分支吗?
它仍然不能控制执行顺序
是否有高级方法可以执行该命令?
synchronization instructions就像__syncthreads()
。
编译器...不应从根本上改变代码的逻辑
CUDA代码的语义与C ++代码的语义不同... if分支的顺序执行不是语义的一部分。
我知道这个答案可能不会令您满意,但这就是事情的好坏所在。