处理展开的循环余数

时间:2012-03-15 19:44:17

标签: performance optimization

美好的一天。

我想请求有关处理展开的循环剩余的技巧的贡献,但需要注意的是循环相当小,是展开因子的1-3倍,例如:

EG。给出B的展开因子

int i = 0;
for (; i < N-N%B; i += B) {
    ...
}
// remainder
for (; i < N; ++i) {
    ...
}

如果B为2,我可以执行以下操作:

// remainder
if (N%2) {
    ....
}

但处理B>2

的好方法是什么

1 个答案:

答案 0 :(得分:0)

您的if (N%2)可以轻松扩展到任何展开因素:

for (; i < N-B+1; i += B) {
    x1; x2; ... xB;
}
if (i < N) {
    x1;
if (i < N-1) {
    x2;
    ...
if (i < N-B+2) {
    xB;
}}}

对于小的展开因子,这可能比第二循环或Duff的设备更有效。

这个版本看起来更好。 gcc 4.6编译几乎相同的代码:

if (i++ < N) {
    x1;
if (i++ < N) {
    x2;
    ...
if (i++ < N) {
    xB;
}}}

如果B是2的幂,这个版本可能会更优。至少gcc为它编译更好的代码。如果N是常量,那么它绝对是最好的。但是如果N都不是常数,B也不是2的幂,那么这种方法的优点就不那么明显了,因为剩余计算效率较低(这通常意味着包括乘法在内的几个指令): / p>

if (N%B > B-2) {
    x1;
if (N%B > B-3) {
    x2;
    ...
if (N%B > 0) {
    xB;
}}}