Edited at

逆アセンブリから最適化の効果を知る

More than 5 years have passed since last update.

Debug ビルドと Release ビルドでコードサイズや実行速度は変わります。

しかし、なんであんなに変わるのか?

その例として、以下のコードを挙げます。


test.cpp

#include <iostream>


int main()
{
return 0;
}

何の変哲もない main 関数です。

これを Visual Studio の 「逆アセンブリ」 ウィンドウで見てみます。


「逆アセンブリ」ウィンドウって?

「逆アセンブリ」ウィンドウとは、

コンパイラによって作成された命令に対応するアセンブリコードやバイトコードなどを見るためのウィンドウです。

「逆アセンブリ」ウィンドウは以下のようにして見ます。


  1. プログラムを実行し、ブレークポイントで止める。

  2. メニューの「デバッグ」 > 「ウィンドウ」 > 「逆アセンブリ」をクリック

すると、「逆アセンブリ」ウィンドウがタブに追加されます。


「逆アセンブリ」ウィンドウでアセンブラコードを見てみよう

先ほどの「test.cpp」を Debug ビルドでビルドして、

「逆アセンブリ」ウィンドウで見たときのアセンブラコードが以下のコードです。

(Debug ビルドはプロジェクトを作成した時の設定そのままです。)


逆アセンブリ(Debug)

#include <iostream>

int main()
{
01101380 push ebp
01101381 mov ebp,esp
01101383 sub esp,0C0h
01101389 push ebx
0110138A push esi
0110138B push edi
0110138C lea edi,[ebp-0C0h]
01101392 mov ecx,30h
01101397 mov eax,0CCCCCCCCh
0110139C rep stos dword ptr es:[edi]
return 0;
0110139E xor eax,eax
}
011013A0 pop edi
011013A1 pop esi
011013A2 pop ebx
011013A3 mov esp,ebp
011013A5 pop ebp
011013A6 ret


Debug ビルドでビルドした時は、これだけの命令が実行されています。

何の変哲もない main 関数しか実行してないにも関わらず、いろんな命令が実行されてますね……。

では、今度は Release ビルドでビルドしたものを見てみます。

(こちらもプロジェクトを作成した時の設定そのままです。)


逆アセンブリ(Release)

#include <iostream>

int main()
{
return 0;
00EE1000 xor eax,eax
}
00EE1002 ret


だいぶスッキリしましたね。

これがコードサイズや実行速度が変わる原因です。

Release ビルドだと最適化処理が働いて、実行される命令がこれだけ削減されます。

こうやって目に見える形にすると、最適化の効果がよくわかりますね。

ただし、最適化でどれだけ命令が削れるかは最適化レベルや最適化をかけるコードに依存しますので、

必ずしもこれだけ削れるとは限りませんので、ご注意を。


最後に

今回は自分の持ってるにわか知識を最大限に使って検証したものです。

間違いのご指摘や補足は大歓迎です!