14

次のテストプログラムを検討してください:

スタック上のループ値

int main( void ) {
    int iterations = 1000000000;

    while ( iterations > 0 )
        -- iterations;
}

スタック上のループ値 (逆参照)

int main( void ) {
    int iterations = 1000000000;
    int * p = & iterations;

    while ( * p > 0 )
        -- * p;
}

ヒープ上のループ値

#include <stdlib.h>

int main( void ) {
    int * p = malloc( sizeof( int ) );
    * p = 1000000000;

    while ( *p > 0 )
        -- * p;
}

-O0 でコンパイルすると、次の実行時間が得られます。

case1.c
real    0m2.698s
user    0m2.690s
sys     0m0.003s

case2.c
real    0m2.574s
user    0m2.567s
sys     0m0.000s

case3.c
real    0m2.566s
user    0m2.560s
sys     0m0.000s

[編集] 以下は、10回の実行の平均です:

case1.c
2.70364

case2.c
2.57091

case3.c
2.57000

最も単純に見える最初のテストケースで実行時間が長くなるのはなぜですか?

私の現在のアーキテクチャは x86 仮想マシン (Archlinux) です。gcc (4.8.0) と clang (3.3) の両方でこれらの結果が得られます。

[編集 1] 生成されたアセンブラー コードは、2 番目と 3 番目のコードが最初のコードよりも多くの命令を持っていることを除いて、ほとんど同じです。

[編集 2] これらのパフォーマンスは (私のシステム上で) 再現可能です。各実行は同じ大きさのオーダーになります。

[編集 3] 最適化されていないプログラムのパフォーマンスはあまり気にしませんが、なぜ遅くなるのか理解できず、興味があります。

4

1 に答える 1