MATLAB アルゴリズムを高速化するために MEX 関数を使用する際のベスト プラクティス
高速化する MATLAB® コードのセクションを選択する場合は、以下を行うことをお勧めします。
実行時間の大半を占めるコードの高速化
実行時間の大半を占める MATLAB コードのセクションを特定します。この部分のコードを、MEX 関数を使用して以下のように高速化します。
コードの該当セクションを別の MATLAB 関数内に配置します。
この MATLAB 関数から MEX 関数を生成します。
元の MATLAB コードからこの MEX 関数を呼び出します。
各 MATLAB 命令の実行時間を計測するには、MATLAB プロファイラーを使用します。
コマンド ラインからプロファイラーを開くには、「
profile viewer
」と入力します。MATLAB エディター ウィンドウからプロファイラーを開くには、[エディター] タブで [実行および時間の計測] をクリックします。
プロファイラーを使用した MATLAB コードの実行時間の計測についての詳細は、パフォーマンス向上のためのコードのプロファイリングを参照してください。
MEX 関数内にループを含める
MATLAB コードのループ内で MEX 関数を呼び出す代わりに、ループを MEX 関数内に含めます。ループを含めることで、ループの実行のたびに MEX 関数を呼び出すオーバーヘッドが排除されます。
たとえば、以下のコードは 1000 行 1000 列の行列 mat
の各行の最大要素を検索します。MEX 関数を使用してセクション 1、2 および 3 を高速化できます。
% Section 1 begins for i = 1:10000 % Section 2 begins max = mat(i,0); % Initialize max for j = 1:10000 % Section 3 begins if (mat(i,j) > max) max = mat(i,j) % Store the current maximum end % Section 3 ends end % Section 2 ends end % Section 1 ends
セクション 1 を MEX 関数を使用して高速化します。MEX 関数が一度だけ呼び出されるようセクション 1 を最初に高速化します。セクション 1 を最初に高速化できない場合は、セクション 2 または 3 をこの順番で高速化します。MEX 関数を使用してセクション 2 (または 3) が高速化される場合、関数は 10000 回 (または 10000 × 10000 回) 呼び出されます。
サポートされていない関数からの MEX 関数生成の回避
高速化する MATLAB コードのセクションが MATLAB Coder™ でサポートされていない多数の関数や言語機能を含んでいないことを確認します。サポートされている関数の一覧は、C/C++ コードの生成でサポートされている関数およびオブジェクトを参照してください。
メモ
場合によっては、サポートされていない関数がいくつか含まれていても、コードのセクションの高速化が必要となることがあります。サポートされていない関数を外部関数として宣言し、関数に対し生成されたコードではなく、元の MATLAB 関数を呼び出します。関数は、coder.extrinsic
を使用するか、feval
ステートメントにラッピングすることで、外部として宣言できます。生成コードでの MATLAB エンジンを使用した関数呼び出しの実行を参照してください。
組み込み MATLAB 関数が実行時間の大半を占める場合の MEX 関数生成の回避
ユーザーが生成したコードが実行時間の大半を占める場合のみ、MEX 関数を使用して MATLAB コードを高速化します。
計算量の多い組み込み MATLAB 関数が実行時間の大半を占める場合は、MEX 関数の生成を避けます。これらの関数はプリコンパイルされ最適化されており、MEX 関数を使用しても MATLAB コードは大幅には高速化されません。こうした関数の例としては、svd
、eig
、fft
、qr
、lu
などが挙げられます。
ヒント
計算量の多い組み込み MATLAB 関数を MEX 関数から呼び出すことができます。coder.extrinsic
を使用するか feval
ステートメントにラッピングして、MATLAB 関数を外部として宣言します。詳細は、生成コードでの MATLAB エンジンを使用した関数呼び出しの実行を参照してください。
MEX 関数呼び出しの最小化
下位レベルで複数の MEX 関数を呼び出す代わりに、1 つの MEX 関数を使用して可能な限りの MATLAB コードを高速化します。これにより、MEX 関数を呼び出す際のオーバーヘッドが最小限に留まります。
たとえば、2 つの関数 testfunc_1
および testfunc_2
を呼び出す関数 testfunc
について考えます。
function [y1,y2] = testfunc(x1,x2) y1 = testfunc_1(x1,x2); y2 = testfunc_2(x1,x2); end
testfunc_1
および testfunc_2
に対し個別に MEX 関数を生成してから testfunc
で MEX 関数を呼び出す代わりに、testfunc
自体に対して MEX 関数を生成します。