计算逻辑方程的最佳选择?

时间:2012-03-20 19:01:36

标签: c performance expression alu

所以,我正在制作一个Hack CPU模拟器,我想知道计算输出的最佳方法是什么。将输出计算压缩成一条不可读的线路比一次一步计算结果更有效吗?编译器是否优化它以使两个选项都正常?基本上,哪些更有效 -

这样:

    word HackALU(word x, word y, bool zx, bool nx, bool zy, bool ny, bool f, bool no)
    {
        x = zx ? 0 : x;
        y = zy ? 0 : y;

        x = nx ? ~x : x;
        y = ny ? ~y : y;

        word result = f ? x + y : x & y;

        return no ? ~result : result;    
    }

或者这个:

    word HackALU(word x, word y, bool zx, bool nx, bool zy, bool ny, bool f, bool no)
    {
        return no ? ~(f ? ((nx ? ~(zx ? 0 : x) : (zx ? 0 : x)) + (ny ? ~(zy ? 0 : y) : (zy ? 0 : y))) : ((nx ? ~(zx ? 0 : x) : (zx ? 0 : x)) & (ny ? ~(zy ? 0 : y) : (zy ? 0 : y)))) : (f ? ((nx ? ~(zx ? 0 : x) : (zx ? 0 : x)) + (ny ? ~(zy ? 0 : y) : (zy ? 0 : y))) : ((nx ? ~(zx ? 0 : x) : (zx ? 0 : x)) & (ny ? ~(zy ? 0 : y) : (zy ? 0 : y))));
    }

3 个答案:

答案 0 :(得分:1)

一个好的现代编译器很可能会为两者生成相同的代码。

答案 1 :(得分:1)

逻辑变化会对代码的性能产生更大的影响,而不是临时的空白/存储。

例如,某些机器没有分支预测(例如PS3 SPU),在这种情况下,通过用数学运算替换分支,您的代码将明确更快

word HackALU(word x, word y, bool zx, bool nx, bool zy, bool ny, bool f, bool no)
{
    x = (zx == 0) * x; // [0 or 1] * x;
    y = (zy == 0) * y;

    x -= (nx != 0) * 2 * x;
    y -= (ny != 0) * 2 * x;

    word result = (f != 0) * (x + y) + (f == 0) * (x & y);

    return (no != 0) * ~result + (no == 0) * result;    
}

答案 2 :(得分:0)

使用这个循环,我实际上显示顶级版本更快:

int n = 0; //optimization busting counter
clock_t start = clock();
    for( word x=0; x<1000; ++x ) {
    for( word y=0; y<1000; ++y ) {
        for( int b = 0; b < 64; ++b ) {
            n += HackALU(x,y,b&0x1,b&0x2,b&0x4,b&0x8,b&0x10,b&0x20);
}   }   }
clock_t end = clock();
printf("finished, elapsed ticks = %d, n = %d\n", end - start, n);

很明显,除非优化器非常好,否则顶级版本的指令会更少......我认为加快速度需要减少分支或确保它们准确预测。