ドキュメンテーション センター

  • 評価版
  • 製品アップデート

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

数学関数と演算子の置換

この例では、コード置換ライブラリを使用して、生成されたコードで演算子と関数を置き換える方法を説明します。以下に示すモデルでは、置換機能を説明します。各モデルの例では、個々の MATLAB ファイルを示し、MATLAB ベースの APIMATLAB ベースの API を使用して演算子と関数の置換を作成する方法および Simulink を使用してそれらを登録登録する方法を説明します。

コード置換ライブラリを使用すると、次のことが可能になります。

  • モデル コードと、外部コードおよびレガシ コードとの優れた統合。コード サイズと検証の労力が削減されます。

  • ターゲット固有の関数実装の使用。組み込みアプリケーションのパフォーマンスを最適化します。

コード置換の機能を次に示します。

  • 数学関数をターゲット固有の関数実装で置換

  • 数学演算をターゲット固有の関数実装で置換

  • 生成されたコードで置換されたものをコンパイルおよびビルドするためのビルド情報の指定

コード置換ライブラリを使用する手順

  • 置換関数エントリのテーブルを作成します。

  • Simulink の sl_customization.m API を使用して 1 つまたは複数のテーブルから構成されるコード置換ライブラリを登録します。

  • [コンフィギュレーション パラメーター] ダイアログ ボックスの [コード生成] ペインの下にある [インターフェイス] ペインを使用してコード置換ライブラリをモデルから選択します。

  • Embedded Coder を使用してモデルのコードを生成します。

これらの手順の詳細は、こちらを参照こちらを参照してください。

組み込み整数の演算子置換の加算と減算

この例では、コード置換ライブラリは、2 つの入力の '+' と '-' (組み込み整数であるデータ型のスカラー演算) を置き換えます。

  • int8、uint8

  • int16、uint16

  • int32、uint32

モデル rtwdemo_crladdsubrtwdemo_crladdsub は、これらの置換を示しています。演算子置換の詳細は、こちらを参照こちらを参照してください。

open_system('rtwdemo_crladdsub')

組み込み整数の乗算および除算演算子の置換

この例では、コード置換ライブラリは、2 つの入力の '*' と '/' (組み込み整数であるデータ型のスカラー演算) を置き換えます。

  • int8、uint8

  • int16、uint16

  • int32、uint32

モデル rtwdemo_crlmuldivrtwdemo_crlmuldiv は、これらの置換を示しています。

open_system('rtwdemo_crlmuldiv')

基本的な演算子における固定小数点演算子の置換

この例で、コード置換ライブラリは、2 つの入力の '+'、'-' 、'*'、および '/' (固定小数点であるデータ型のスカラー演算) を置き換えます。置換は、次の項目の一致として定義できます。

  • 入力と出力における特定の勾配スケーリング/バイアス スケーリングの組み合わせ。

  • 入力と出力における特定の 2 進小数点スケーリングの組み合わせ。

  • 入力と出力間の相対的なスケーリング。

  • 入力と出力全体で同じ勾配値とゼロの正味バイアス。

モデル rtwdemo_crlfixptrtwdemo_crlfixpt は、これらの置換を示しています。

メモ: モデルで固定小数点データ型を使用するには、Fixed-Point Designer™ のライセンスが必要です。

open_system('rtwdemo_crlfixpt')

MATLAB Coder™ における加算および減算演算子の置換

この例では、コード置換ライブラリは、2 つの入力の '+' と '-' (codegen コマンドを使用する際の整数データ型のスカラー演算) を置き換えます。

演算子置換の詳細は、こちらを参照こちらを参照してください。MATLAB Coder を使用して組み込み可能な C コードを生成する方法の詳細は、こちらを参照こちらを参照してください。

この例には、MATLAB ファイル addsub_two_int16.m が必要です。ファイルを一時フォルダーにコピーしてください。この手順では、一時フォルダーへの書き込み権限が必要です。

MATLAB ファイルを表示するには、こちらを参照こちらを参照してください。

coderdir = [tempname filesep 'coderdir'];
if ~exist(coderdir,'dir')
    mkdir(coderdir);
end
codersrc = ...
    fullfile(matlabroot,'toolbox','rtw','rtwdemos','crl_demo','addsub_two_int16.m');
copyfile(codersrc,coderdir,'f');
codercurdir = pwd;
cd(coderdir);

コード置換ライブラリを使用するための MATLAB Coder の設定

ビルドするコンフィギュレーション パラメーターを設定し、演算入力データ型を定義します。コード置換テーブルの定義ファイルを表示するには、こちらを参照こちらを参照してください。

addpath(fullfile(matlabroot,'toolbox','rtw','rtwdemos','crl_demo'));
sl_refresh_customizations;
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Addition & Subtraction Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

t = int16(2); %#ok<NASGU>

C ソース ファイルへの MATLAB プログラムのコンパイル

MATLAB プログラムをコンパイルします。コード置換ライブラリを参照するコンフィギュレーション パラメーターと、codegen コマンドへの入力パラメーターとして前述の手順で定義された入力クラスの例を使用します。

codegen -config cfg -c addsub_two_int16 -args {t, t};

MATLAB Coder で生成されたコードの確認

コンパイル後は、生成されたソース コードを検査できます。生成されたコードを表示するには、こちらを参照こちらを参照してください。

数学関数の置換

コード置換は、各種の関数の置換をサポートしています。サポートされている関数の一覧については、こちらを参照こちらを参照してください。

モデル rtwdemo_crlmathrtwdemo_crlmath は、これらの置換を示しています。数学関数の置換の詳細は、こちらを参照こちらを参照してください。

cd(codercurdir);
open_system('rtwdemo_crlmath')

行列演算子の置換

コード置換は、次の行列演算の置換をサポートしています。

加算、減算、乗算、転置、共役、エルミート

モデル rtwdemo_crlmatopsrtwdemo_crlmatops は、これらの置換の一部を示しています。サポートされているデータ型は、以下のとおりです。

  • single、double

  • int8、uint8

  • int16、uint16

  • int32、uint32

  • csingle、cdouble

  • cint8、cuint8

  • cint16、cuint16

  • cint32、cuint32

  • 固定小数点整数

  • 混合データ型 (入力ごとに異なるデータ型)

行列演算子置換についての詳細は、こちらを参照こちらを参照してください。

open_system('rtwdemo_crlmatops')

BLAS サポート

行列の乗算は Basic Linear Algebra Subroutines (BLAS) にマップできます。以下の演算は、BLAS サブルーチンにマップできます。

  • 行列の乗算

  • 1 つまたは両方の入力の転置を伴う行列の乗算

  • 1 つまたは両方の入力のエルミート演算を伴う行列の乗算

モデル rtwdemo_crlblasrtwdemo_crlblas は、BLAS xGEMM と xGEMV サブルーチンへのマッピングを示しています。

open_system('rtwdemo_crlblas')

その他のスカラー演算子の置換

コード置換は、次のスカラー演算の置換をサポートしています。

加算、減算、乗算、除算、複素共役を含む複雑な演算。データ型のキャスト、左シフト、算術右シフト、論理右シフトを含むその他のスカラー演算。

モデル rtwdemo_crlscalaropsrtwdemo_crlscalarops は、これらの置換の一部を示しています。サポートされているデータ型は、以下のとおりです。

  • single、double

  • int8、uint8

  • int16、uint16

  • int32、uint32

  • csingle、cdouble

  • cint8、cuint8

  • cint16、cuint16

  • cint32、cuint32

  • 固定小数点整数

  • 混合データ型 (入力ごとに異なるデータ型)

スカラー演算子の置換についての詳細は、こちらを参照こちらを参照してください。

open_system('rtwdemo_crlscalarops')

カスタム エントリ

コード置換は、カスタム エントリの作成をサポートしています。RTW.TflCFunctionEntryML または RTW.TflCOperationEntryML のいずれかからサブクラス化することによって独自のエントリを作成できます。エントリクラスは、一致するロジックをカスタマイズする、または一致したエントリを変更する do_match メソッドを実装しなければなりません。do_match は、あらかじめ設定された固定のシグネチャをもたなければなりません。モデル rtwdemo_crlcustomentryrtwdemo_crlcustomentry では、カスタム エントリを使用して独自の一致する関数を作成する方法を説明します。このモデルでは、追加の実装関数の引数として定数を挿入することによって一致したエントリを変更する方法を説明します。

カスタム エントリの詳細は、こちらを参照こちらを参照してください。

open_system('rtwdemo_crlcustomentry')

MATLAB 関数の置換

コードの置換では、MATLAB 関数ブロックに指定された MATLAB 関数の置換をサポートしています。関数を置換用に選択するには、MATLAB 関数ブロック内に 'coder.replace' を指定します。この機能は、MATLAB 関数の次の置換をサポートしています。

  • 単入力/複数入力

  • 単出力/複数出力

  • スカラーおよび行列の入力/出力

モデル rtwdemo_crlcoderreplacertwdemo_crlcoderreplace は、これらの要件の一部を示しています。サポートされているデータ型は、以下のとおりです。

  • single、double

  • int8、uint8

  • int16、uint16

  • int32、uint32

  • csingle、cdouble

  • cint8、cuint8

  • cint16、cuint16

  • cint32、cuint32

  • 固定小数点整数

  • 混合データ型 (入力ごとに異なるデータ型)

MATLAB 関数の置換についての詳細は、こちらを参照こちらを参照してください。

open_system('rtwdemo_crlcoderreplace')

関数実装のデータ配置

この例では、コード置換ライブラリで置換関数に渡された非スカラー データの配置を指定する方法を示しています。一部のターゲット固有の関数実装では、アプリケーション パフォーマンスを最適化するためにデータを配置する必要があります。関数実装のためにデータ配置を構成するには

  • テーブル エントリのデータ配置要件を指定します。実装関数引数の配置は個別にまたはまとめて指定することができます。

  • データ配置機能と構文をコンパイラに指定します。AlignmentSpecification オブジェクトを sl_customization.m または rtwTargetInfo.m ファイルに指定されたレジストリ エントリの TargetCharacteristics オブジェクトに追加します。

モデル rtwdemo_crlalignrtwdemo_crlalign は、これらの配置仕様を示しています。関数引数にデータ配置を指定する方法は、こちらを参照こちらを参照してください。コンパイラの配置属性の指定方法の詳細は、こちらを参照こちらを参照してください。

この例は、GCC、Clang または MSVC コンパイラを使用するように構成されています。

open_system('rtwdemo_crlalign')

データ配置からのパフォーマンスの向上

このモデルでは、SIMD 命令で使用されるデータを配置するためにコード置換を使用して得られるパフォーマンスを説明します。モデル rtwdemo_crlalignperfrtwdemo_crlalignperf は、これらのパフォーマンス向上を示しています。

この例は、GCC、Clang または MSVC コンパイラを使用するように構成されています。

open_system('rtwdemo_crlalignperf')

cc = rtwprivate('getMexCompilerInfo');
isDaDemoSupported = strcmpi(cc.comp.Manufacturer,'GNU') || ...
                    strcmpi(cc.comp.Manufacturer,'Apple') || ...
                    strcmpi(cc.comp.Manufacturer,'Microsoft');
if ~isDaDemoSupported
  recMsg = ['Use "mex -setup" to select either GCC, Clang, or MSVC and restart this ' ...
            'example'];
  warning(['The model "%s" is configured to use either GCC, Clang, or MSVC to create ' ...
          'a Data Aligned Executable. %s.'], 'rtwdemo_crlalignperf',recMsg); %#ok<CTPCT>
end

ベースラインの生成

ベースラインは、ANSI ライブラリを選択してモデルをビルドしてから、生成された実行可能ファイルを 10 回実行することで生成されます。このモデルは、画像処理アルゴリズムの一環で要素単位の行列の乗算を使用します。行列の乗算は、画像の各ピクセルを処理する過程で何度も実行されます。プロファイリング フックは実行可能ファイルの実行時間を測定します。

if (isDaDemoSupported)
  coderdir = [tempname filesep 'coderdir'];
  if ~exist(coderdir,'dir')
      mkdir(coderdir);
  end
  cd(coderdir);
  set_param('rtwdemo_crlalignperf', 'CodeReplacementLibrary', 'C89/C90 (ANSI)');
  rtwbuild('rtwdemo_crlalignperf');
  iterations = 10;
  T1 = zeros(iterations, 1);
  for idx = 1:iterations
      evalc(['!', fullfile('.', 'rtwdemo_crlalignperf')]);
      evalc(['load ', fullfile('.','rtwdemo_crlalignperf.mat')]);
      T1(idx) = rt_yout.signals(1).values;
  end
  if exist('rtwdemo_crlalignperf_ANSI', 'dir')
      rmdir('rtwdemo_crlalignperf_ANSI', 's');
  end
  movefile('rtwdemo_crlalignperf_ert_rtw', 'rtwdemo_crlalignperf_ANSI');
else
  warning('Unable to build model "%s". %s.', 'rtwdemo_crlalignperf',recMsg);
end
### Starting build procedure for model: rtwdemo_crlalignperf
### Successful completion of build procedure for model: rtwdemo_crlalignperf

データを配置した実行可能ファイルの生成

要素単位の行列の乗算を SIMD 固有の呼び出しに割り当てるライブラリを選択してから、モデルをビルドすることにより、最適化されデータを配置した実行可能ファイルを生成します。SIMD 固有の呼び出しは、渡されるデータに配置要件を課します。最適化された実行可能ファイルは 10 回実行されます。この場合も、プロファイリング フックがタイミング データを取得します。

if (isDaDemoSupported)
  set_param('rtwdemo_crlalignperf', 'CodeReplacementLibrary', ...
            'SIMD Single 5x5 Element-wise Mul');
  rtwbuild('rtwdemo_crlalignperf');
  T2 = zeros(iterations, 1);
  for idx=1:iterations
      evalc(['!', fullfile('.', 'rtwdemo_crlalignperf')]);
      evalc(['load ', fullfile('.','rtwdemo_crlalignperf.mat')]);
      T2(idx) = rt_yout.signals(1).values;
  end
  if exist('rtwdemo_crlalignperf_SIMD', 'dir')
      rmdir('rtwdemo_crlalignperf_SIMD','s');
  end
  movefile('rtwdemo_crlalignperf_ert_rtw', 'rtwdemo_crlalignperf_SIMD');
else
  warning('The Data Aligned Executable for the model "%s" could not be generated. %s.' ...
          ,'rtwdemo_crlalignperf',recMsg);
end
### Starting build procedure for model: rtwdemo_crlalignperf
### Successful completion of build procedure for model: rtwdemo_crlalignperf

ベースラインとデータを配置した実行可能ファイルでのタイミング結果の比較

ベースラインおよびデータを配置した実行可能ファイルを実行して取得されたタイミング データがグラフに表示されます。グラフは、SIMD 演算にデータ配置を使用することによりデータ並列演算の実行を効果的に高速化できることを示します。

if (isDaDemoSupported)
  T1(T1<0) = NaN;    % The profile counter may overflow.
  T2(T2<0) = NaN;
  t = [min(T1), min(T2)];
  h = figure;

  bar([NaN, t(1), NaN, t(2), NaN]);
  set(gca, 'XLim', [0.5, 5.5], 'XTickLabel', {'', 'ANSI Multiply', '', 'SIMD Multiply', ''}, ...
           'TickLength', [0 0], 'YLim', [0, max(t) * 1.3], 'YTick', []);
  ylabel('Execution Time (CPU Cycles)');
  % annotate the plot
  annotation('textbox', get(gca, 'Position'), ...
             'String', ['Execution Speed Increased By: ', num2str((1 - t(2)/t(1))*100, '%2.0f'), '%'], ...
             'LineStyle', 'none', 'FitBoxToText', 'off', 'FitHeightToText', 'on', ...
             'FontWeight', 'bold', 'FontSize', 12, 'HorizontalAlignment', 'center');
  % annotate first bar (simple multiply without alignment)
  text('Position', [2, t(1)], 'String', int2str(t(1)), 'LineStyle', 'none', ...
       'FontSize', 12, 'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom');

  % annotate second bar (SIMD Multiply without alignment)
  text('Position', [4, t(2)],  'String', int2str(t(2)), 'LineStyle', 'none', ...
       'FontSize', 12, 'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom');
else
  warning('The Data Alignment Performance Gain example could not be executed. %s.' ...
        , recMsg);
end

コード置換ライブラリ用のビューアー

テーブルとそのエントリを検証するためにビューアーが提供されています。たとえば、テーブル 'crl_tablemuldiv' を表示する場合、コマンドは次のようになります。

crl = crl_table_muldiv;
me = RTW.viewTfl(crl);

コード置換ビューアーの詳細は、こちらを参照こちらを参照してください。

ビルド サポート

コード置換テーブルの各エントリでは、次のようなビルド情報を指定できます。

  • ヘッダー ファイルの依存関係

  • ソース ファイルの依存関係

  • 追加のインクルード パス

  • 追加のソース パス

  • 追加のリンク フラグ

さらに、メソッド RTW.copyFileToBuildDir を使用して、エントリによって指定されたソース ファイルとヘッダー ファイルをローカルにコピーできます。コンパイル情報の指定方法の詳細は、こちらを参照こちらを参照してください。

メモ: 置換関数の実装は行われないため、この例のモデルはコード生成用にのみ構成されます。

予約識別子のサポート

エントリによって定義される各関数の実装は、一意の識別子として予約されます。その他の識別子は、ヘッダー ファイルごとにテーブルで指定できます。追加の予約識別子を指定すると、重複するシンボルやその他の識別子関連のコンパイルとリンクの問題の発生を防ぐことができます。

予約識別子の指定方法の詳細は、こちらを参照こちらを参照してください。

コード置換ライブラリの例の削除

モデルの例の利用が終了したら、次のコマンドを使用してコード置換ライブラリの例を削除し、モデルの例を終了することができます。

rmpath(fullfile(matlabroot,'toolbox','rtw','rtwdemos','crl_demo'));
sl_refresh_customizations;

close_system('rtwdemo_crladdsub', 0)
close_system('rtwdemo_crlmuldiv', 0)
close_system('rtwdemo_crlfixpt', 0)
close_system('rtwdemo_crlmath', 0)
close_system('rtwdemo_crlmatops', 0)
close_system('rtwdemo_crlblas', 0)
close_system('rtwdemo_crlscalarops', 0)
close_system('rtwdemo_crlcustomentry', 0)
close_system('rtwdemo_crlcoderreplace', 0)
close_system('rtwdemo_crlalign', 0)
close_system('rtwdemo_crlalignperf', 0)
if ~isempty(me)
    me.delete;
end
drawnow;
if exist('h','var') && ishghandle(h)
  close(h);
end
clear h;
clear crl;
clear me;
clear coderdir;
clear codersrc;
clear codercurdir;
clear n1;
clear cfg;
clear t;
clear cc;
clear recMsg;
clear isDaDemoSupported;
clear T1;
clear T2;
clear idx;
clear iterations;
clear rt_tout;
clear rt_yout;
この情報は役に立ちましたか?