最適化とは,ソースからオブジェクトコードを生成する過程において,効率の良いオブジェクトコードを生成するための手法です.GCCではソースプログラムを字句解析,構文解析,意味解析した後,中間ファイルとしてアセンブラのコードを出力します.その次にアセンブラのコードを見直して最適化します.
基本はプログラムの実行効率の向上を図ることです.最適化の方法として,以下のものがあげられます.
・命令の実行回数を削減する
・RISCチップの場合,1命令に変換できる場合にコードを書き換える
・命令実行の高速化
命令の実行回数を削減するため,以下のようなコードの書き換えが行われます.
● 例1 共通の部分式を置き換える
リスト7のようなコードが考えられます.このコードで(1)の部分は,
res = 10 * z;
と置き換えることができます.
〔リスト7〕共通の部分式を置き換える
|
int main(int argc, char* argv[])
{
int x;
int y;
int z;
int res;
x = 10;
y = 20;
z = x + y;
/************他の処理*****************/
res = 10 * (x + y); (1)
return res;
}
|
|
しかし,並列処理や変数zのアドレスがハードウェアのアドレスとリンクしていた場合,その最適化処理はバグを作り出してしまいます.
● 例2 定数を置き換える
リスト8のようなコードが考えられます.このコードは単純にリスト9のように書き換えられます.
〔リスト8〕定数を置き換える
|
int main(int argc, char* argv[])
{
int x;
int y;
int z;
x = 10 + 30;
y = 20;
z = x + y;
/************他の処理*****************/
return z;
}
|
|
〔リスト9〕定数を置き換えた結果
|
int main(int argc, char* argv[])
{
/************他の処理*****************/
return 10 + 30 +20;
}
|
|
● 例3 式のループ外への移動
リスト10のようなコードが考えられます.このコードはリスト11のように書き換えられます.
〔リスト10〕式のループ外への移動
|
for(ix=0;ix<_Max;ix++)
{
x = 10;
y = x * 20;
・・・・・
}
|
|
〔リスト11〕式をループ外へ移動した結果
|
y = 200;
for(ix=0;ix<_Max;ix++)
{
・・・・・
}
|
|
やはり並列処理や変数yのアドレスがハードウェアのアドレスとリンクしていた場合,その最適化処理はバグを作り出してしまいます.
● 例4 冗長なループを変換する
リスト12のようなコードが考えられます.このコードはリスト13のように書き換えられます.
〔リスト12〕式のループ外への移動
|
for(ix=0;ix<_Max;ix++)
{
a[ix] = 0;
}
for(ix=0;ix<_Max;ix++)
{
b[ix] = 0;
}
|
|
〔リスト13〕式をループ外へ移動した結果
|
for(ix=0;ix<_Max;ix++)
{
a[ix] = 0;
b[ix] = 0;
}
|
|
● 例5 演算の置き換え
次のようなコード,
y = x ^ 2;
は,
y = x * xと等価で,このほうが効率よく処理できるため書き換えられます.
|