メインコンテンツ

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

並列 for ループ (parfor) を使用したアルゴリズムの高速化

R2026a

生成コード内の並列 for ループ (parfor)

並列 for ループ (parfor ループ) を含む MATLAB® コードから MEX 関数または C/C++ コードを生成して、実行を高速化できる場合があります。

標準の MATLAB for ループと同様、parfor ループは、ある範囲の値にわたって一連のステートメント (ループ本体) を実行します。しかし for ループとは異なり、parfor ループの反復はターゲット ハードウェアの複数のコアで並列に実行できます。

反復を並列に実行することで、生成されたコードの実行速度が大幅に改善される場合があります。詳細については、parfor ループによる実行速度の改善を参照してください。

メモ

並列実行は、元の MATLAB コードではなく、生成された MEX 関数または C/C++ コードのみで行われます。MATLAB コードを高速化するには、parfor ループから MEX 関数を生成します。次に、MEX 関数をコードから呼び出します。MEX 関数の生成の詳細については、MATLAB Coder を使用したコード生成の概要を参照してください。

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 ループの本体では以下の構成を使用しないでください。

    • parfor ループを別の parfor ループ内で使用することはできます。ただし、内側の parfor は通常の for ループとして単一のスレッドで実行されます。

      parfor ループの内部で、別の parfor ループを含む関数を呼び出すことができます。

    • break または return ステートメントは、parfor ループ内では使用できません。

    • parfor ループ内でグローバル変数を書き込むことはできません。

    • parfor ループ内ではリダクションを MATLAB クラスに使用できません。

    • parfor ループ内ではリダクションを char 変数に使用できません。

      たとえば、次の MATLAB コードの C コードを生成できません。

      c = char(0);
      parfor i=1:10
        c = c + char(1);
      end
      parfor ループでは、MATLAB は c を double にします。コード生成では、c は型を変更できません。

    • parfor ループ内ではリダクションに coder.ceval を使用できません。たとえば、次の parfor ループのコードを生成できません。

      parfor i=1:4
        y=coder.ceval('myCFcn',y,i);
      end
      代わりに、coder.ceval を使用して C コードを呼び出すローカル関数を記述し、この関数を parfor ループ内で呼び出します。以下に例を示します。
      parfor i=1:4
        y = callMyCFcn(y,i);
      end
      ...
      function y = callMyCFcn(y,i)
       y = coder.ceval('mCyFcn', y , i);
      end

    • parfor ループ内では、coder.extrinsic を使用して外部関数を呼び出すことはできません。外部呼び出しを含む関数の呼び出しは、実行時のエラーを引き起こします。

    • MATLAB Coder は関数を parfor ループにインライン化しません。coder.inline('always') を使用する関数も同様です。

    • parfor ループ内では coder.unroll は使用できません。

      parfor ループ内でループが展開されると、MATLAB Coder は変数を分類できません。以下に例を示します。

      for j=coder.unroll(3:6)
        y(i,j)=y(i,j)+i+j;
      end
      このコードは次のように展開されます。
      y(i,3)=y(i,3)+i+3;
      ...
      y(i,6)=y(i,6)+i+6;
      変数 y は parfor ループ内においてさまざまな方法でインデックス付けされているので、MATLAB Coder は展開されたコードで y を分類できません。

      MATLAB Coder は、自身が分類できない変数をサポートしません。詳細は、parfor ループ内での変数の分類を参照してください。

    • varargin または varargout は parfor ループ内では使用できません。