次のことを考慮してください
while(true)
{
if(x>5)
// Run function A
else
// Run function B
}
x が常に 5 未満の場合、Visual Studio コンパイラは最適化を行いますか? つまり、like は x が 5 より大きいかどうかをチェックせず、常に関数 B を実行します。
次のことを考慮してください
while(true)
{
if(x>5)
// Run function A
else
// Run function B
}
x が常に 5 未満の場合、Visual Studio コンパイラは最適化を行いますか? つまり、like は x が 5 より大きいかどうかをチェックせず、常に関数 B を実行します。
x
これは、コンパイラが常に未満になることを「認識」しているかどうかによって異なり5
ます。
はい、ほとんどすべての最新のコンパイラはブランチを削除できます。ただし、コンパイラは、ブランチが常に一方向に進むことを証明できる必要があります。
最適化できる例を次に示します。
int x = 1;
if (x > 5)
printf("Hello\n");
else
printf("World\n");
分解は次のとおりです。
sub rsp, 40 ; 00000028H
lea rcx, OFFSET FLAT:??_C@_06DKJADKFF@World?6?$AA@
call QWORD PTR __imp_printf
x = 1
おそらく。よりも小さいです5
。したがって、コンパイラはブランチを削除できます。
しかし、この例では、常に5未満を入力しても、コンパイラーはそれを認識しません。入力を想定する必要があります。
int x;
cin >> x;
if (x > 5)
printf("Hello\n");
else
printf("World\n");
分解は次のとおりです。
cmp DWORD PTR x$[rsp], 5
lea rcx, OFFSET FLAT:??_C@_06NJBIDDBG@Hello?6?$AA@
jg SHORT $LN5@main
lea rcx, OFFSET FLAT:??_C@_06DKJADKFF@World?6?$AA@
$LN5@main:
call QWORD PTR __imp_printf
ブランチは残ります。ただし、実際にはブランチから関数呼び出しを引き上げたことに注意してください。したがって、コードは次のように最適化されています。
const char *str = "Hello\n";
if (!(x > 5))
str = "World\n";
printf(str);