根据文档,在计算能力1.x的设备中,编译器默认会内联__device__
个函数,但对于计算能力为2.x或更高的设备,只有在认为合适的情况下才会这样做。编译器。什么时候不适合?还有__noinline__
和__forceinline__
等限定符。在哪些情况下最好不要内联__device__
函数?
答案 0 :(得分:12)
内联的编译器启发式推测可以评估内联带来的潜在性能优势,因为它消除了对包括编译时在内的其他特性的函数调用开销。积极的内联可能导致非常大的代码导致非常长的编译时间。通过观察为许多不同内核生成的代码,CUDA编译器似乎在绝大多数情况下都是内联的。请注意,在某些情况下,内联当前是不可能的,例如当被调用函数位于不同的,单独编译的编译单元中时。
根据我的经验,覆盖编译器的内联启发式是有意义的实例很少见。我使用__noinline__
来限制代码大小,从而减少过多的编译时间。使用__noinline__
对我注意到的注册压力没有可预测的影响。内联可能允许更激进的代码移动,例如加载调度,这可能会增加寄存器压力,而不内联可能会因ABI对寄存器的使用限制而增加寄存器压力。我从未发现使用__noinline__
提高性能的情况,但当然这种情况可能存在,可能是由于指令缓存效应。
答案 1 :(得分:5)
我已经体验过,如果强制_device_
函数调用是内联编译的,它可以将运行时减少一半。就在最近的一个中,我进行了函数调用(它只传递了5个变量来实现)内联,并且内核执行时间从9.5ms减少到4.5ms(几乎一半)。如果你认为你想要执行相同的内核数百万次,总运行时间为一周或更长时间(就像我的情况和许多其他工作在CFD或MD项目上的那样),与巨大的相比,增加编译时间并不重要在运行时保存。
总而言之,我认为值得尝试对运行时的内联函数调用影响,尤其是对于运行时间很长的代码。