並列 for ループ (parfor) を使用したアルゴリズムの高速化
生成コード内の並列 for ループ (parfor)
並列 for ループ (parfor
ループ) を含む MATLAB® コードから MEX 関数または C/C++ コードを生成して、実行を高速化できる場合があります。
標準の MATLAB for
ループと同様、parfor
ループは、ある範囲の値にわたって一連のステートメント (ループ本体) を実行します。しかし for
ループとは異なり、parfor
ループの反復はターゲット ハードウェアの複数のコアで並列に実行できます。
反復を並列に実行することで、生成されたコードの実行速度が大幅に改善される場合があります。詳細については、parfor ループによる実行速度の改善を参照してください。
メモ
並列実行は、元の MATLAB コードではなく、生成された MEX 関数または C/C++ コードのみで行われます。MATLAB コードを高速化するには、parfor
ループから MEX 関数を生成します。次に、MEX 関数をコードから呼び出します。詳細は、MATLAB アルゴリズムを高速化するためのワークフローを参照してください。
MATLAB コードで parfor
を使用するには、Parallel Computing Toolbox™ のライセンスが必要です。
MATLAB Coder™ ソフトウェアは、Open Multiprocessing (OpenMP) アプリケーション インターフェイスを使用して共有メモリ、マルチコア コードの生成をサポートします。分散型の並列処理が必要な場合は、Parallel Computing Toolbox 製品を使用してください。既定では、MATLAB Coder は使用可能なすべてのコアを使用します。使用するスレッドの数を指定すると、追加のコアが使用可能な場合でも、MATLAB Coder はスレッドに対し指定数までのコアしか使用しません。詳細は、parfor
を参照してください。
ループ本体は複数のスレッドで並列に実行できるため、一定の制限に従わなければなりません。MATLAB Coder ソフトウェアが parfor
の仕様に準拠しないループを検出すると、エラーが発生します。詳細は、parfor の制限を参照してください。
parfor ループによる実行速度の改善
parfor
ループは複数のスレッドを同じループで同時に計算できるため、類似の for
ループより実行速度が上がる場合があります。
parfor
ループの本体の各実行は、反復と呼ばれます。スレッドは任意の順序で、また互いに独立して反復を評価します。各反復は独立しているため、これらを同期する必要はありません。スレッド数がループ反復数と同じである場合、各スレッドはループの 1 つの反復を実行します。スレッド数より反復数が多い場合、一部のスレッドは 1 回を超えるループ反復を実行します。
たとえば、100 回の反復からなるループが 20 のスレッドで実行される場合、各スレッドは同時にループを 5 回ずつ反復します。反復数が多い、または個々の反復処理が長いなどの理由でループの実行に時間がかかる場合、複数のスレッドを使用して実行時間を大幅に削減できます。ただし、この例では、スレッドの作成と削除などの並列処理によるオーバーヘッドのため、速度は 20 倍にならない可能性があります。
parfor ループを使用する場合
以下の場合に parfor
を使用します。
簡単な計算の反復が多数ある。
parfor
はループの反復をグループに分け、各スレッドにより反復の 1 つのグループが実行されるようにします。ループ反復の実行に時間がかかる。
parfor
は異なるスレッド上で反復を同時に実行します。この同時実行では、個々の反復にかかる時間は削減されませんが、ループ処理にかかる全体的な時間は大幅に削減される可能性があります。
parfor ループを使用しない場合
以下の場合、parfor
は使用しないでください。
ループの反復が他の反復に依存する。反復を並列に実行すると誤った結果になる場合があります。
ループの反復が他の反復に依存する場合に
parfor
の使用を避けるため、MATLAB Coder では変数の厳密な分類が指定されています。詳細は、parfor ループ内での変数の分類を参照してください。MATLAB Coder ソフトウェアがparfor
仕様に準拠しないループを検出した場合は、コードを生成せずにエラーを出力します。リダクションは、ループ反復は独立していなければならないというルールに対する例外です。"リダクション変数" は、すべての反復に同時に依存するが反復順序には依存しない値を累積します。詳細については、リダクション変数を参照してください。
単純な計算を実行する数回の反復しかない。
メモ
反復回数が少ないループについては、並列処理のオーバーヘッドがあるために実行が高速化されない場合があります。こうしたオーバーヘッドには、スレッドの作成、スレッド間のデータ同期、スレッドの削除などにかかる時間が含まれます。
parfor ループの構文
parfor
ループには、次の構文を使用します。parfor i = InitVal:EndVal parfor (i = InitVal:EndVal)
最大数のスレッドを指定するには、次の構文を使用します。
parfor (i = InitVal:EndVal,NumThreads)
詳細は、parfor
を参照してください。
parfor の制限
parfor
ループは次の構文をサポートしていません。parfor (i=initVal:step:endVal) parfor i=initVal:step:endVal
Open Multiprocessing (OpenMP) アプリケーション インターフェイスをサポートするコンパイラを使用しなければなりません。サポートされるコンパイラを参照してください。OpenMP をサポートしていないコンパイラを使用する場合は、MATLAB Coder は
parfor
ループをfor
ループとして扱います。生成された MEX 関数または C/C++ コードでは、ループ反復は単一スレッドで実行されます。OpenMP アプリケーション インターフェイスは JIT MEX コンパイルと互換性がありません。JIT コンパイルが OpenMP をサポートしないを参照してください。
ループ インデックスの型は、ターゲット ハードウェアにおいて整数型で表現可能でなければなりません。生成されたコード内でマルチワード タイプを必要としない型を使用してください。
スタンドアロン コード生成の
parfor
では、実行可能ファイルまたはライブラリのビルドにツールチェーン アプローチが必要です。parfor
ループの本体では以下の構成を使用しないでください。