Main Content

生成コードでの for ループの自動並列化

並列 for ループの反復はターゲット ハードウェアの複数のコアで同時に実行できます。コードのセクションを並列化すると、生成コードの実行速度が大幅に改善される場合があります。parfor ループによる実行速度の改善を参照してください。

MATLAB® コードから C/C++ コードを生成する際に、並列 for ループを自動的に生成できます。自動並列化は、手動操作なしでシーケンシャル コードをマルチスレッド コードに変換するコンパイラ変換です。

for ループの自動並列化では、C/C++ ターゲットに対して次のビルド タイプがサポートされます。

  • MEX

  • スタティック ライブラリ

  • ダイナミック リンク ライブラリ

  • 実行可能ファイル

MATLAB Coder アプリを使用した for ループの並列化

for ループの自動並列化を有効にするには、MATLAB Coder™ アプリの [コード生成] ステップで、[詳細設定]、[速度]、[自動並列化を有効にする] を選択します。

GUI for Enable Automatic Parallelization

コマンド ラインでの for ループの並列化

コマンド ライン インターフェイスを使用して for ループの並列化を有効にできます。関数 autoparExample について考えます。

function x = autoparExample(x)
%#codegen
for i = 10:numel(x)
    x(i) = sqrt(x(i));
end
end

並列 for ループを自動的に生成するには、次のコマンドを実行します。

cfg = coder.config('lib');
cfg.EnableAutoParallelization = 1;
x = rand(1,2000);
codegen -config cfg autoparExample -args {x} -report
Code generation successful: View report

生成されたコードとコード洞察の検査

コード生成レポートを開いて検査します。

生成コード

for ループの上に生成されている Open Multiprocessing (OpenMP) プラグマを確認します。

void autoparExample(double x[2000])
{
  int i;
  if (!isInitialized_autoparExample) {
    autoparExample_initialize();
  }
#pragma omp parallel for num_threads(omp_get_max_threads()) private(i)

  for (i = 0; i < 1991; i++) {
    x[i + 9] = sqrt(x[i + 9]);
  }
}

ループの横にある緑色で強調表示されたガターは、コードの並列化される部分を示しています。

Highlighted parallel for loops

コード洞察

[コード洞察] タブの [自動並列化の問題] で、生成されたコードで並列化されなかった for ループに関する詳細情報を確認できます。

たとえば、特定のコード洞察を確認するには、前のセクションで定義した関数 autoparExample のコードを再生成します。入力引数に指定するサイズを小さくします。

cfg = coder.config('lib');
cfg.EnableAutoParallelization = 1;
x = rand(1,1000);
codegen -config cfg autoparExample -args {x} -report

入力引数のサイズが自動並列化のしきい値よりも小さいため、生成されたコードには並列 for ループは含まれません。コードの並列化されていない部分に関する詳細情報を確認するには、レポートを開いて [コードの洞察]、[自動並列化の問題] をクリックします。

Code insights about non-parallelized part of the code

for ループの自動並列化の無効化

特定のループについて逐次実行の方が優れたパフォーマンスが得られる場合は、そのループの自動並列化を無効にできます。特定の for ループを並列化しないようにするには、MATLAB コードでそのループの直前に coder.loop.parallelize('never') プラグマを配置します。このプラグマは、EnableAutoParallelization 設定をオーバーライドします。また、このプラグマは MATLAB コードで明示的に定義されている for ループのみをサポートします。明示的なループと暗黙的なループの詳細については、次のセクションを参照してください。

たとえば、コード ジェネレーターは次のループを並列化しません。

% Pragma to disable automatic parallelization of for-loops
coder.loop.parallelize('never');
for i = 1:n
    y(i) = y(i)*sin(i);
end

coder.loop.parallelize を参照してください。

暗黙的な for ループの並列化

前のセクションで使用したサンプル関数 autoparExample には明示的な for ループが含まれています。しかし、MATLAB コードには、作成したコードに明示的に表示されない暗黙的な for ループを含めることもできます。たとえば、MATLAB 関数 mtimes は 2 つの行列を乗算するため、行列の要素に対してループ反復を暗黙的に実行する必要があります。

自動並列化では MATLAB コード内で暗黙的なループがサポートされます。たとえば、以下の関数 autoparExample_implicit を考えます。

function y = autoparExample_implicit(y)
%#codegen
y = y * 17; % Generates implicit for loop
end

次のコマンドを実行してコードを生成します。

cfg = coder.config('lib');
cfg.EnableAutoParallelization = 1;
y = rand(1,2000);
codegen -config cfg autoparExample_implicit -args {y} -report

レポートを開き、生成されたコードを検査します。生成されたコードには、乗算演算の並列 for ループが含まれています。

void autoparExample_implicit(double y[2000])
{
  int i;
  if (!isInitialized_autoparExample_implicit) {
    autoparExample_implicit_initialize();
  }
#pragma omp parallel for num_threads(omp_get_max_threads()) private(i)

  for (i = 0; i < 2000; i++) {
    y[i] *= 17.0;
  }

使用に関するメモと制限

参考

| | | | |

関連するトピック