LoginSignup
22
21

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-05-18

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 ビルドだと最適化処理が働いて、実行される命令がこれだけ削減されます。

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

ただし、最適化でどれだけ命令が削れるかは最適化レベルや最適化をかけるコードに依存しますので、
必ずしもこれだけ削れるとは限りませんので、ご注意を。

最後に

今回は自分の持ってるにわか知識を最大限に使って検証したものです。
間違いのご指摘や補足は大歓迎です!

22
21
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
21