Main Content

並列 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 Coderparfor ループを for ループとして扱います。生成された MEX 関数または C/C++ コードでは、ループ反復は単一スレッドで実行されます。

  • OpenMP アプリケーション インターフェイスは JIT MEX コンパイルと互換性がありません。JIT コンパイルが OpenMP をサポートしないを参照してください。

  • ループ インデックスの型は、ターゲット ハードウェアにおいて整数型で表現可能でなければなりません。生成されたコード内でマルチワード タイプを必要としない型を使用してください。

  • スタンドアロン コード生成の parfor では、実行可能ファイルまたはライブラリのビルドにツールチェーン アプローチが必要です。コード ジェネレーターでテンプレート makefile アプローチを使用する原因となるような設定変更は行わないでください。プロジェクトまたは構成でテンプレート makefile を使用を参照してください。

  • parfor ループの本体では以下の構成を使用しないでください。

    •  入れ子にされた parfor ループ

    •  break および return ステートメント

    •  グローバル変数

    •  MATLAB クラスのリダクション

    •  変数 char のリダクション

    •  外部 C コードを使用したリダクション

    •  外部関数呼び出し

    •  関数のインライン化

    •  ループの展開

    •  varargin/varargout