プログラミング

ソースコードを変更せず組込みアプリケーションの性能改善

<span id="hs_cos_wrapper_name" class="hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text" style="" data-hs-cos-general-type="meta_field" data-hs-cos-type="text" >ソースコードを変更せず組込みアプリケーションの性能改善</span>
 

IAR Embedded Workbenchは組込み業界で最も効率の良いコードを出力します。種々の設定により、ソースコードを変更することなくアプリケーションの性能を最大限に引き出すことが可能です。ここでは、いくつかの具体的な性能改善の方法をご紹介します。

具体的な性能改善の方法

サイズまたは実行速度の優先度

最適化のレベルと種類について、アプリケーション全体または個々のファイルに対して、指定できます。#pragmaを使えば関数単位での指定も可能です。

最適化の目的は、コードサイズを削減し、かつ実行速度を改善することです。この2つの目的のうち一方しか満たせない場合、コンパイラはユーザが指定した優先度に基づいて処理を行います。

各変換の効果を精査することで、より良い結果が得られることがあります。例えば、速度優先の最適化である関数インライン展開によって、サイズ優先の設定よりコードサイズが小さくなる場合があります。

サイズまたは実行速度の優先度

小さいメモリモデルの選択

ターゲットで利用可能なメモリモデルのうち、アプリケーションが許容する最も小さいモデルを選択することで、以下のベネフィットが得られる場合があります。

  • 命令が使用するアドレス幅が小さくなる
  • よりコードサイズの小さい命令が利用できる
  • よりコードサイズの小さいポインタが利用できる
  • 実行効率があがる
  • コード効率があがる

アプリケーションの実行環境に合わせたランタイム関数の性能改善

ランタイム関数は、デフォルトでは、サイズを最優先でコンパイルされています。アプリケーションの実行速度を改善したい場合、ランタイム関数を速度優先でビルドしなおすことが効果的です(ランタイム関数は製品版ライセンスのみソース提供)。

ロケール、ファイル記述子、マルチバイト文字など、いくつかの標準ライブラリに対し、アプリケーションが必要とするサポートのレベルを指定できます。

scanf関数の入力およびprintf関数の出力に対して、対応する形式を指定できます(対応する形式を増やすとコードサイズが増加)。デフォルトの指定では、コードサイズは最小ではありません。

ランタイム関数の性能改善

アプリケーションが必要とするサポートのレベルを指定

適切な型の選択

変数の型は、性能改善の視点で、コードサイズおよび実行速度の両方に大きく影響します。

  • アプリケーションに最も適した型を選択しましょう
  • char型のデフォルトを符号なしにすることで、算術演算の代わりにビット演算が可能となる場合があります

適切な型の選択

ターゲット固有オプションの確認

実行性能を引き出すため、ターゲット固有のオプションを使用しましょう。以下は一例です。

  • 効率的なアドレッシングモードにより、効率的なメモリアクセス命令を出力できます。
  • 定数・変数にレジスタを割り付けることで、メモリアクセスを削減し、演算をレジスタの値で直接実行できます。
  • 関数の先頭アドレスおよび命令を偶数番地に整列することで、実行速度が向上します。
  • バイト単位でオブジェクトを整列することで、保存に必要なメモリが減る一方、コードサイズが大きくなることがあります。

テストとリリースを意識したベンチマーク

  • 組込みシステムのベンチマークでは対象とするアプリケーションの特性を考慮しましょう。

  • アプリケーションは大抵の場合、ベンチマークには十分ですが、リリースできるものか確認しましょう。例えば、リンカは参照しないコードや変数を削除しますが、全てのリンカがこの機能を持つわけではありません。

  • テスト対象のコードがテスト用のコードに影響されないことを確認しましょう。例えば、下記のサンプルコードのprintf関数がそれ以外の箇所に影響しないか確認しましょう。

テストとリリースを意識したベンチマーク

  • 複数のコンパイラのビルド結果を比較しましょう。コードをインライン展開するコンパイラがある一方、ライブラリ関数呼び出しで実現するコンパイラもあります。

  • 適切なベンチマークのため、開発するアプリケーションについて熟知しましょう!