Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

生成コードのパフォーマンスと可読性を微調整するためのインライン化の制御

インライン化は、関数呼び出しをその関数の内容 (本文) と置き換える最適化手法です。インライン化によって関数呼び出しのオーバーヘッドが排除されるため、速度が向上します。

アプリケーションによっては、コードのインライン化が多すぎると次のような特定の欠点が生じる可能性もあります。

  • インライン化によって、生成される C/C++ コードが長くなり、コードの可読性が低下する可能性があります。たとえば、ソース MATLAB® コードで特定の関数 foo を何度も呼び出すとします。コード ジェネレーターが foo を常にインライン化する場合、foo は呼び出されるたびにインライン化されるため、生成コードのサイズは増加します。ただし、これが生じるには、呼び出しサイトが異なっていなければなりません。たとえば、foo がループ内で何度呼び出されても、インライン化によってコード サイズが大きくなることはありません。

  • ライン外の関数の場合、関数のローカル変数のスタック領域は、関数が返ったときに解放されます。インライン関数では、関数が返されても、ローカル変数によってスタック領域は占有されたままになります。したがって、RAM またはスタック領域が制限されている場合は、関数のインライン化を制限することをお勧めします。

コード ジェネレーターは、内部のヒューリスティックな方法を使用して、生成コードで関数をインライン化するかどうかを判定します。このヘルプ トピックでは、このようなヒューリスティックな方法を微調整し、アプリケーションの速度、可読性およびスタック領域の要件を満たすコードを生成する方法について説明します。

特定の MATLAB 関数のインライン化の制御

特定の MATLAB 関数を常にインライン化する、または決してインライン化しないようにコード ジェネレーターに指示するには、その関数の本体内で coder.inline('always') 命令と coder.inline('never') 命令を使用します。これらの命令の詳細については、coder.inline を参照してください。

コード生成設定を使用したインライン化の制御

記述した関数用に生成されるコードと MathWorks® 関数用に生成されるコードでは速度および可読性の要件が異なる場合があります。特定のコード生成設定を使用すると、生成コード ベースのこれら 2 つの部分に関するインライン化の動作を、それらの間の境界で個別に制御できます。このような設定は、MEX コードとスタンドアロン コードの両方の生成に適用されます。

コード構成パラメーター説明オプション

コード構成オブジェクトの場合: InlineBetweenUserFunctions

MATLAB Coder™ アプリの場合: [すべての設定] タブの [ユーザー関数間のインライン]

記述した関数が別の記述した関数を呼び出すすべての呼び出しサイトにおけるインライン化の動作を制御します。

'Always' | 'Speed' (既定値) | 'Readability' | 'Never'

コード構成オブジェクトの場合: InlineBetweenMathWorksFunctions

MATLAB Coder アプリの場合: [すべての設定] タブの [MathWorks 関数間のインライン]

MathWorks 関数が別の MathWorks 関数を呼び出すすべての呼び出しサイトにおけるインライン化の動作を制御します。

'Always' | 'Speed' (既定値) | 'Readability' | 'Never'

コード構成オブジェクトの場合: InlineBetweenUserAndMathWorksFunctions

MATLAB Coder アプリの場合: [すべての設定] タブの [ユーザー関数と MathWorks 関数の間のインライン]

記述した関数が MathWorks 関数を呼び出すか、MathWorks 関数が記述した関数を呼び出すすべての呼び出しサイトにおけるインライン化の動作を制御します。

'Always' | 'Speed' (既定値) | 'Readability' | 'Never'

オプションの説明:

  • 'Always':呼び出しサイトでインライン化を常に実行します。

  • 'Speed':内部のヒューリスティックな方法を使用して、呼び出しサイトでインライン化を実行するかどうかを判定します。通常、この設定を使用すると高度に最適化されたコードが生成されます。この設定が既定の設定です。

  • 'Readability':非常に小さい関数の呼び出しを除き、関数呼び出しのインライン化をほぼ実行しません。可能な限り、速度を大幅に低下させることなくコードのモジュール性を維持します。非常に読みやすいコードが生成されます。

  • 'Never':関数呼び出しのインライン化を実行しません。最大限の可読性が得られます。この設定では、生成コードのパフォーマンスが大幅に低下する可能性があります。

メモ

インライン パラメーターで選択したオプションにコード ジェネレーターが厳密に従わない場合があります。たとえば、MathWorks 関数の本体に coder.inline('never') 命令が含まれている場合に InlineBetweenMathWorksFunctions'Always' に設定すると、コード ジェネレーターは coder.inline 命令を優先し、その関数をインライン化しません。詳細については、異なるインライン化制御間の相互作用を参照してください。

インライン化戦略の例

これは、生成コードの速度と可読性のバランスを取るインライン化戦略の例です。次のアクションを同時に実行するようにコード ジェネレーターに指示します。

  • 可読性を高めるため、生成コードの速度が低下するとしても、記述したコードのモジュール性を維持します。この動作のためには、InlineBetweenUserFunctions'Readability' に設定します。

  • コードの可読性が低下するとしても、MathWorks 関数の高度に最適化されたコードを生成します。コード ベースのこの部分を検査する可能性は低いためです。この動作のためには、InlineBetweenMathWorksFunctions'Speed' に設定します。

  • 生成コードで、記述した関数と MathWorks 関数を分離して、生成コードの外観が MATLAB コードとあまり異ならないようにします。この動作のためには、InlineBetweenUserAndMathWorksFunctions'Readability' に設定します。

異なるインライン化制御間の相互作用

  • MATLAB 関数の本体内に配置された coder.inline('always') 命令または coder.inline('never') 命令は、codegen オプションやコード構成設定などのグローバルなインライン化制御の効果をオーバーライドします。coder.inline を参照してください。

    特定の MathWorks 関数には、これらの関数がグローバルなインライン化設定とどのように相互作用するかに影響する coder.inline 命令の呼び出しが含まれます。たとえば、MathWorks 関数の本体に coder.inline('never') 命令が含まれている場合に InlineBetweenMathWorksFunctions'Always' に設定すると、コード ジェネレーターは coder.inline 命令を優先し、その関数をインライン化しません。

  • codegen コマンドの -O disable:inline オプションと -O enable:inline オプションは、3 つのコード構成パラメーター InlineBetweenUserFunctionsInlineBetweenMathWorksFunctions および InlineBetweenUserAndMathWorksFunctions の各値をオーバーライドします。

例: 記述した関数と MathWorks® 関数の間の境界におけるインライン化の制御

この例では、記述した関数が MathWorks 関数を呼び出すか、MathWorks 関数が記述した関数を呼び出すすべての呼び出しサイトにおけるインライン化の動作を制御する方法を示します。

MathWorks 関数を呼び出す関数の定義

double の配列 x を入力として受け入れ、関数besselyを使用して入力配列を処理し、x と同じ型およびサイズをもつ配列を返す MATLAB 関数 useBessely を定義します。

type useBessely.m
function out = useBessely(x)
out = x + bessely(3,x);
end

既定のインライン化設定を使用したコードの生成

関数 useBessely の C++ スタティック ライブラリを生成します。入力を 1100 列の double 型に指定します。インライン化設定に既定値を使用します。これらの既定値によって生成コードの速度が最適化されます。ソース コードの生成のみを行い、ソース コードをビルドしないようにコード ジェネレーターに指示する -c フラグを使用します。

codegen -c -lang:c++ -config:lib useBessely -args {zeros(1,100)} -report
Code generation successful: To view the report, open('codegen/lib/useBessely/html/report.mldatx')

コード生成レポートを開き、生成されたコードを検査します。MathWorks 関数 bessely に対して個別の C++ 関数が生成されていないことを確認します。コード ジェネレーターにより、関数 bessely のコードが、ファイル useBessely.cpp に含まれている C++ 関数 useBessely にインライン化されています。

変更されたインライン化設定を使用したコードの生成

C++ スタティック ライブラリを生成するためのコード構成オブジェクト cfg を定義します。InlineBetweenUserAndMathWorksFunctions プロパティを 'Never' に設定します。この設定は、コード ジェネレーターに対して、記述した関数と MathWorks 関数を生成コードで分離するように指示します。その結果、生成された C++ コードは効率が低下しますが、インライン化されたコードよりも読みやすくなります。

cfg = coder.config('lib');
cfg.TargetLang = 'C++';
cfg.InlineBetweenUserAndMathWorksFunctions = 'Never';

cfg をコード構成オブジェクトとして使用してコードを生成します。入力を 1100 列の double 型に指定します。ソース コードの生成のみを行い、ソース コードをビルドしないようにコード ジェネレーターに指示する -c フラグを使用します。

codegen -c -config cfg useBessely -args {zeros(1,100)} -report
Code generation successful: To view the report, open('codegen/lib/useBessely/html/report.mldatx')

コード生成レポートを開き、生成されたコードを検査します。C++ 関数 useBessely は、MathWorks 関数 bessely に対して生成されたコードを含む別の C++ 関数 coder::bessely を呼び出します。その結果、生成された C++ 関数 useBessely は、記述した MATLAB 関数 useBessely と同様の外観になります。

type codegen/lib/useBessely/useBessely.cpp
//
// Prerelease License - for engineering feedback and testing purposes
// only. Not for sale.
// File: useBessely.cpp
//
// MATLAB Coder version            : 23.2
// C/C++ source code generated on  : 27-Jul-2023 15:00:23
//

// Include Files
#include "useBessely.h"
#include "bessely.h"
#include "rt_nonfinite.h"

// Function Definitions
//
// Arguments    : const double x[100]
//                creal_T out[100]
// Return Type  : void
//
void useBessely(const double x[100], creal_T out[100])
{
  coder::bessely(x, out);
  for (int i{0}; i < 100; i++) {
    out[i].re += x[i];
  }
}

//
// File trailer for useBessely.cpp
//
// [EOF]
//

参考

| | | |

関連するトピック