さて、私のシステムでこれをテストしました。完全な最適化により、コンパイラーは質問なしでカウント = 50 を作成しました。最適化を行わない場合、通常は 2 番目のバージョンがわずかに高速でしたが、まったく無視できる程度でした。
逆アセンブル: 両方のループのコードはまったく同じですが、比較が 100 で 1 回、50 で 1 回です (実行時間を長くできるように、数値を少し上げました)。
for(int i = 0; i< 100; i++) {
00F9140B mov dword ptr [i],0
00F91412 jmp main+5Dh (0F9141Dh)
00F91414 mov eax,dword ptr [i]
00F91417 add eax,1
00F9141A mov dword ptr [i],eax
00F9141D cmp dword ptr [i],64h
00F91421 jge main+88h (0F91448h)
for(int j = 0; j< 50; j++)
00F91423 mov dword ptr [j],0
00F9142A jmp main+75h (0F91435h)
00F9142C mov eax,dword ptr [j]
00F9142F add eax,1
00F91432 mov dword ptr [j],eax
00F91435 cmp dword ptr [j],32h
00F91439 jge main+86h (0F91446h)
{
count++;
00F9143B mov eax,dword ptr [count]
00F9143E add eax,1
00F91441 mov dword ptr [count],eax
}
00F91444 jmp main+6Ch (0F9142Ch)
}
00F91446 jmp main+54h (0F91414h)
外側の大きなループ、内側の小さなループ、内側の小さなループ、外側の大きなループの唯一の違いは、ジャンプを行う頻度です。
00F91439 jge main+86h (0F91446h)
to
00F91446 jmp main+54h (0F91414h)
そして、ループ変数の初期化:
00F91423 mov dword ptr [j],0
00F9142A jmp main+75h (0F91435h)
以下の部分をスキップしながら、新しいループごとに。
00F9142C mov eax,dword ptr [j]
00F9142F add eax,1
00F91432 mov dword ptr [j],eax
内側のループの反復ごとに追加のコマンド: mov、add、mov、ただし mov / jmp はありません
初期化された各内部ループの追加コマンド: mov、jmp、および多くの場合、JGE を true にします。
したがって、内側のループを 50 回実行すると、その JGE は 50 回しか成立しないため、そこで 50 回のジャンプを行いますが、内側のループを 100 回実行すると、100 回ジャンプする必要があります。それがコードの唯一の違いです。この場合、それはほとんど違いがなく、ほとんどの場合、メモリアクセスがループの順序よりも多くの速度低下を引き起こしていることに遭遇します。唯一の例外: 分岐予測を回避するためにループを適切に並べ替えることができることがわかっている場合。したがって、ループをどちらかの方法で順序付けする価値があるのは、次の 2 つです。
-メモリアクセス
-分岐予測
それ以外の場合、影響はまったく無視できます。