在什么类型的循环是最好用的CUDA使用#pragma unroll指令?(In what types

2019-08-02 07:30发布

在CUDA可以展开使用循环#pragma unroll指令,以提高通过增加指令级并行性能。 该#pragma可以选择跟一个数字,指定多少次循环必须展开。

不幸的是,文档不给时,应使用此指令的具体方向。 由于与已知的行程计数的小循环已经由编译器展开,应该#pragma披在更大的循环使用吗? 在小循环具有可变柜台? 而关于解开的可选号码是什么? 也有关于CUDA特定循环展开推荐文档?

Answer 1:

目前还没有任何又快又狠的规则。 在CUDA编译器具有至少两个开卷,每一个所述NVVM或Open64前端的内部,和一个在PTXAS后端。 在一般情况下,他们往往会展开循环非常积极,所以我发现自己使用#pragma unroll 1 (防止展开)往往比其他任何展开属性。 用于关闭循环展开的原因有两方面:

(1)当一个环被完全展开, 寄存器压力可以增加。 例如,索引成小的本地存储器阵列可以成为编译时间常数,允许编译器对本地数据放入寄存器。 完全摊平也可以趋于加长基本块,从而允许纹理和全局负载的更积极的调度,这可能需要额外的临时变量,因而寄存器。 增加寄存器的压力可能会导致由于溢出注册性能较低。

(2)部分展开的循环通常需要一定量的预先计算和清理代码来处理不属于展开因子的准确倍数循环计数。 对于短行程计数的循环,这方面的开销可以淹没任何的性能提升从展开的循环了,导致展开后性能降低。 虽然编译包含启发式下这些限制,寻找合适的循环,启发式不能总是提供最好的决定。

在极少数情况下,我发现,提供手动比自动使用编译器对性能有小的有益作用(在个位数百分比典型增益)较高的展开因素。 这些都是典型的内存密集型代码情况下,较大的展开因子允许从循环开销最小化有利于全球或纹理加载,还是很紧的约束计算循环更积极的调度。

与展开因素玩的东西,应该发生在优化过程中后期,由于编译器的默认覆盖大多数情况下,人会在实践中遇到的问题。



Answer 2:

这是一个工具,你可以用它来展开循环。 当它应该/不应该被用来将根据你的代码有很大的差异的细节(什么是循环例如内)。 真的没有想到,除了你的代码将是什么样子展开VS卷起并认为,如果这将是更好的展开任何良好的通用技巧。



文章来源: In what types of loops is it best to use the #pragma unroll directive in CUDA?