1

C でプリ インクリメント オペレーターとポスト インクリメント オペレーターのプロファイリングを行ったところ (マイクロ最適化の目的ではなく、好奇心から!)、いくつかの驚くべき結果が得られました。ポスト インクリメント オペレータの方が遅いと思っていましたが、すべてのテストで (自明ではない) 高速であることが示されました。-Sgcc でフラグを使用して生成されたアセンブリ コードを調べたところ、 post には 1 つの余分な命令があります (予想どおり)。誰でもこれを説明できますか?Arch Linux で gcc 4.8.1 を使用しています。

これが私のコードです。

編集: コードに整数オーバーフロー エラーがあります。質問には影響しませんが、実際の反復回数は渡された引数とは異なることに注意してください。

Post.c:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    if (argc < 2) {
        printf("Missing required argument\n");
        exit(1);
    }
    int iterations = atoi(argv[1]);

    int x = 1;
    int y;

    int i;
    for (i = 0; i < iterations; i++) {
        y = x++;
    }

    printf("%d\n", y);
}

Pre.c:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    if (argc < 2) {
        printf("Missing required argument\n");
        exit(1);
    }
    int iterations = atoi(argv[1]);

    int x = 1;
    int y;

    int i;
    for (i = 0; i < iterations; i++) {
        y = ++x;
    }

    printf("%d\n", y);
}

結果は次のとおりです。

$ gcc post.c -o post
$ gcc pre.c -o pre
$ I=100000000000; time ./post $I; time ./pre $I
1215752192

real    0m2.777s
user    0m2.777s
sys     0m0.000s
1215752193

real    0m3.140s
user    0m3.137s
sys     0m0.003s

少し前にタイミングスクリプトも書きました。同じ結果が得られた実行:

$ I=100000000000; comptime "./pre $I" "./post $I"
3193 3133 3157 3143 3133 3153 3147 3150 3143 3146 3143
2743 2767 2700 2727 2700 2697 2727 2710 2680 2783 2700
Mean 1: 3149.18
Mean 2: 2721.27
SD 1: 6.1800
SD 2: 21.2700

出力はほとんど自明ですが、アイデアは、両方のプログラムを 10 回 (デフォルトで) 実行し、結果の平均と標準偏差をミリ秒単位で計算することです。

post.cおよびpre.c用に gcc によって生成されたアセンブリ コードをペーストビンに含めました。

この議論を再び持ち出して申し訳ありませんが、これらの数字は私には奇妙に思えます。

4

1 に答える 1