
IAR Embedded Workbenchは組込み業界で最も効率の良いコードを出力します。種々の設定により、ソースコードを変更することなくアプリケーションの性能を最大限に引き出すことが可能です。ここでは、いくつかの具体的な性能改善の方法をご紹介します。
サイズまたは実行速度の優先度
最適化のレベルと種類について、アプリケーション全体または個々のファイルに対して、指定できます。#pragmaを使えば関数単位での指定も可能です。
最適化の目的は、コードサイズを削減し、かつ実行速度を改善することです。この2つの目的のうち一方しか満たせない場合、コンパイラはユーザが指定した優先度に基づいて処理を行います。
各変換の効果を精査することで、より良い結果が得られることがあります。例えば、速度優先の最適化である関数インライン展開によって、サイズ優先の設定よりコードサイズが小さくなる場合があります。
小さいメモリモデルの選択
ターゲットで利用可能なメモリモデルのうち、アプリケーションが許容する最も小さいモデルを選択することで、以下のベネフィットが得られる場合があります。
- 命令が使用するアドレス幅が小さくなる
- よりコードサイズの小さい命令が利用できる
- よりコードサイズの小さいポインタが利用できる
- 実行効率があがる
- コード効率があがる
アプリケーションの実行環境に合わせたランタイム関数の性能改善
ランタイム関数は、デフォルトでは、サイズを最優先でコンパイルされています。アプリケーションの実行速度を改善したい場合、ランタイム関数を速度優先でビルドしなおすことが効果的です(ランタイム関数は製品版ライセンスのみソース提供)。
ロケール、ファイル記述子、マルチバイト文字など、いくつかの標準ライブラリに対し、アプリケーションが必要とするサポートのレベルを指定できます。
scanf関数の入力およびprintf関数の出力に対して、対応する形式を指定できます(対応する形式を増やすとコードサイズが増加)。デフォルトの指定では、コードサイズは最小ではありません。
適切な型の選択
変数の型は、性能改善の視点で、コードサイズおよび実行速度の両方に大きく影響します。
- アプリケーションに最も適した型を選択しましょう
- char型のデフォルトを符号なしにすることで、算術演算の代わりにビット演算が可能となる場合があります
ターゲット固有オプションの確認
実行性能を引き出すため、ターゲット固有のオプションを使用しましょう。以下は一例です。
- 効率的なアドレッシングモードにより、効率的なメモリアクセス命令を出力できます。
- 定数・変数にレジスタを割り付けることで、メモリアクセスを削減し、演算をレジスタの値で直接実行できます。
- 関数の先頭アドレスおよび命令を偶数番地に整列することで、実行速度が向上します。
-
バイト単位でオブジェクトを整列することで、保存に必要なメモリが減る一方、コードサイズが大きくなることがあります。
テストとリリースを意識したベンチマーク
-
組込みシステムのベンチマークでは対象とするアプリケーションの特性を考慮しましょう。
-
アプリケーションは大抵の場合、ベンチマークには十分ですが、リリースできるものか確認しましょう。例えば、リンカは参照しないコードや変数を削除しますが、全てのリンカがこの機能を持つわけではありません。
-
テスト対象のコードがテスト用のコードに影響されないことを確認しましょう。例えば、下記のサンプルコードのprintf関数がそれ以外の箇所に影響しないか確認しましょう。
-
複数のコンパイラのビルド結果を比較しましょう。コードをインライン展開するコンパイラがある一方、ライブラリ関数呼び出しで実現するコンパイラもあります。
-
適切なベンチマークのため、開発するアプリケーションについて熟知しましょう!