2017-02-20 7 views
2

ずつが、私たちは10個の正の整数拳を印刷するにはC++で、次のコードスニペットを考えてみましょうトラバースよりもループしています従いが速く1

x =1; 

cout<< x; 

x++; 

cout<< x; 

などなど...

は、それが速いか遅いべきである理由として、何らかの理由はありますか?それは言語によって異なるのでしょうか?

+0

操作の数を比較します。それは同じです。 – lukai

+4

ループが速くなる理由は何ですか?はい。キャッシング。 – phonetagger

+0

@lukai操作の数は同じではないと思います:非ループ版では比較が起こっていません。 (実際にはこのようなアプローチはほとんど役に立たないが) –

答えて

1

ループでは、実際のマシンレベルの命令は同じで、したがって同じアドレスになります。明示的なステートメントでは、命令のアドレスが異なります。したがって、ループの場合、CPUの命令キャッシュは、後者の場合には起こり得ない性能向上をもたらす可能性がある。

実際には小さい範囲(10)の場合、その差はごくわずかです。ループの長さがかなり長い場合は、より明確に表示されます。

3

この質問はthis oneに似ています。私は以下のmy answer to that questionの抜粋をコピーしました...(数字は異なります; 11対50、分析は同じです)

あなたが検討しているのは、手作業によるループアンローリングです。ループアンローリングは、ループに含まれるオーバーヘッドを減らすためにコンパイラが時々使用する最適化です。コンパイラは、コンパイル時にループの反復回数を知ることができる(すなわち、反復回数は、定数が他の定数に基づく計算を含んでいても定数である)場合にのみ実行できます。場合によっては、コンパイラはループを展開する価値があると判断することがありますが、完全に展開しないことがよくあります。たとえば、あなたの例では、コンパイラは、ループの50回の繰り返しから5回のループ本体の10回の反復まで、ループを展開するのがスピード上の利点であると判断することがあります。ループ変数はまだそこにありますが、ループカウンターを50回比較する代わりに、コードは比較を10回だけ実行する必要があります。これはトレードオフです。ループ本体の5つのコピーがキャッシュ内の5倍のスペースを消費するため、同じ命令の余分なコピーをロードすると、すでにキャッシュされている多くの命令がキャッシュから削除されますキャッシュと、キャッシュに残したいと思っていたかもしれません。また、ループ本体命令の4つの余分なコピーをメインメモリからロードすることは、ループがまったく展開されていない場合にキャッシュから既にロードされた命令を単に取り込むことよりもはるかに長い時間を要する。

このように、ループ本体のコピーを1つだけ使用してループロジックをそのままにしておくと、しばしばより有利です。 (つまり、ループをまったく展開しないでください)

関連する問題