0

それで、私は Hack CPU エミュレーターを作成していますが、出力を計算する最良の方法は何かと考えていました。一度に 1 ステップずつ結果を計算するよりも、出力計算を判読できない 1 行にまとめる方が効率的でしょうか? コンパイラは、両方のオプションが問題ないように最適化しますか? 基本的に、これらのうちどれがより効率的か -

これ:

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

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

        単語の結果 = f ? x + y : x & y;

        いいえを返しますか?〜結果:結果;    
    }

またはこれ:

    word HackALU(word x, word y, bool zx, bool nx, bool zy, bool ny, bool f, bool 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))));
    }
4

3 に答える 3

1

優れた最新のコンパイラは、ほとんどの場合、両方に対して同一のコードを生成します。

于 2012-03-20T19:17:00.397 に答える
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;    
}
于 2012-03-21T17:37:35.053 に答える
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);

オプティマイザーが本当に優れていない限り、最上位バージョンの命令が少ないことは明らかです...高速化するには、分岐を減らすか、それらが正確に予測されるようにする必要があると思います。

于 2012-03-21T16:46:10.720 に答える