循环优化 - 返工

时间:2014-01-22 14:16:49

标签: c optimization

考虑以下伪代码:

x1 = DEFAULT_VAL_1;
y1 = DEFAULT_VAL_2;
for (i = 0; i < CONST1; i++) {
    x0 = *x0buffer++;
    y0 = *y0buffer++;
    if (x0*y1 > y0*x1)
    {
        x1 = x0;
        y1 = y0;
        pos = i;
    }
}

感兴趣的输出x1y1pos

你能推荐一种方法来优化它,以避免if语句吗?

3 个答案:

答案 0 :(得分:1)

如果您使用的是x86,那么您不相信您的编译器会对此进行优化,而您愿意进行汇编,这样就可以解决问题:

x1 = DEFAULT_VAL_1;
y1 = DEFAULT_VAL_2;
for (i = 0; i < CONST1; i++) {
    x0 = *x0buffer++;
    y0 = *y0buffer++;

    asm (
        "cmp %3, %4\n\t"
        "cmovl %5, %0\n\t"
        "cmovl %6, %1\n\t"
        "cmovl %7, %2\n\t"
        : "+g" (pos)
        , "+g" (x1)
        , "+g" (y1)
        : "r" (x0*y1)
        , "r" (y0*x1)
        , "r" (i)
        , "r" (x0)
        , "r" (y0)
        : "cc"
    );
}

答案 1 :(得分:1)

你可以试试这个版本

   for (i = 0; i < CONST1; i++) {
    x0 = *x0buffer++;
    y0 = *y0buffer++;
    c = (x0*y1 > y0*x1);

        x1 = x0 *c + x1 * (c^1);
        y1 = y0 *c + y1 * (c^1);
        pos = i* c + pos * (c^1);    
}

看起来代码的计算密集程度要高得多,但在并行架构上,这将比原始版本执行得更快。

希望有所帮助

答案 2 :(得分:0)

假设您的字节长度为8位(根据需要进行修改)并且您的整数在MSB中有符号,那么这可能会更快或更快:

#define masked_replace(mask, a, b) a += ( (b) - (a) ) & (mask)

int mask = y0*x1 - x0*y1; // signed(!!!) int
mask >>= sizeof(mask) * 8 - 1;
masked_replace(mask, x1, x0);
masked_replace(mask, y1, y0);
masked_replace(mask, pos, i);