Main Content

parfor

并行 for 循环

说明

示例

parfor LoopVar = InitVal:EndVal; Statements; end 在生成的 MEX 函数中或在共享内存多核平台上并行运行的 C/C++ 代码中创建一个循环。

parfor 循环对 InitValEndval 之间的 LoopVar 值执行 StatementsLoopVar 指定由整数值组成的向量,这些值按 1 递增。

示例

parfor (LoopVar = InitVal:EndVal, NumThreads); Statements; end 在创建并行 for 循环时,最多使用 NumThreads 个线程。

示例

全部折叠

parfor 循环生成一个 MEX 函数,以在最大可用核数上执行。

编写一个 MATLAB® 函数 test_parfor,它在 parfor 循环中调用快速傅里叶变换函数 fft。由于循环迭代是并行运行的,因此该计算可以比类似的 for 循环更快地完成。

function a = test_parfor %#codegen
  a = ones(10,256);  
  r = rand(10,256);
  parfor i = 1:10
    a(i,:) = real(fft(r(i)));
  end
end

test_parfor 生成一个 MEX 函数。在 MATLAB 命令行中输入:

codegen test_parfor

codegen 在当前文件夹中生成一个 MEX 函数 test_parfor_mex

运行 MEX 函数。在 MATLAB 命令行中输入:

test_parfor_mex

该 MEX 函数使用可用的核运行。

parfor 循环生成 MEX 函数时,请指定最大线程数。

编写一个 MATLAB 函数 specify_num_threads,该函数使用输入 u 来指定 parfor 循环中的最大线程数。

function y = specify_num_threads(u) %#codegen
  y = ones(1,100);
  % u specifies maximum number of threads
  parfor (i = 1:100,u)
    y(i) = i;
  end
end

specify_num_threads 生成一个 MEX 函数。使用 -args 0 指定输入的类型。在 MATLAB 命令行中输入:

% -args 0 specifies that input u is a scalar double
% u is typecast to an integer by the code generator
codegen -report specify_num_threads -args 0

codegen 在当前文件夹中生成一个 MEX 函数 specify_num_threads_mex

运行该 MEX 函数,指定它最多在四个线程上并行运行。在 MATLAB 命令行中输入:

specify_num_threads_mex(4)

生成的 MEX 函数最多在四个核上运行。如果可用核少于四个,MEX 函数将在调用时的最大可用核数上运行。

在为 parfor 循环生成 MEX 函数之前禁用并行化。

编写一个 MATLAB 函数 test_parfor,它在 parfor 循环中调用快速傅里叶变换函数 fft

function a = test_parfor %#codegen
  a = ones(10,256);  
  r = rand(10,256);
  parfor i = 1:10
    a(i,:) = real(fft(r(i)));
  end
end

test_parfor 生成一个 MEX 函数。禁用 OpenMP,这样,codegen 便不会生成可在多个线程上运行的 MEX 函数。

codegen -O disable:OpenMP test_parfor

codegen 在当前文件夹中生成一个 MEX 函数 test_parfor_mex

运行 MEX 函数。

test_parfor_mex

MEX 函数在单一线程上运行。

如果禁用并行化,MATLAB Coder™ 会将 parfor 循环视为 for 循环。该软件会生成在单一线程上运行的 MEX 函数。禁用并行化以比较生成的 MEX 函数或 C/C++ 代码的串行和并行版本的性能。您还可以禁用并行化来调试并行版本的问题。

输入参数

全部折叠

循环索引变量,其初始值为 InitVal,结束值为 EndVal

循环索引变量 Loopvar 的初始值。此参数与 EndVal 一起指定 parfor 范围向量,形式必须为 M:N

循环索引变量 LoopVar 的结束值。此参数与 InitVal 一起指定 parfor 范围向量,形式必须为 M:N

要在 parfor 循环中执行的一系列 MATLAB 命令。

如果您在同一行中放置多个语句,请用分号分隔这些语句。例如:

parfor i = 1:10
 arr(i) = rand(); arr(i) = 2*arr(i)-1;
end

要使用的最大线程数。如果您指定上限,MATLAB Coder 使用的线程数不能超过此数量,即使有额外的可用核也是如此。如果您请求的线程数超过可用核数,MATLAB Coder 将使用在调用时可用的最大核数。如果循环迭代数少于线程数,一些线程将不执行任何工作。

如果 parfor 循环无法在多个线程上运行(例如,如果只有一个核可用或 NumThreads 为 0),MATLAB Coder 会以串行方式执行循环。

限制

  • 必须使用支持 Open Multiprocessing (OpenMP) 应用程序接口的编译器。请参阅支持的编译器。如果使用不支持 OpenMP 的编译器,则 MATLAB Coder 会将 parfor 循环视为 for 循环。在生成的 MEX 函数或 C/C++ 代码中,循环迭代在单个线程上运行。

  • OpenMP 应用程序接口与 JIT MEX 编译不兼容。请参阅 JIT Compilation Does Not Support OpenMP

  • 不要在 parfor 循环内使用以下结构:

    • parfor 循环体中,不能使用 coder.extrinsic 调用外部函数。

    • 不能在 parfor 循环内写入全局变量。

    • MATLAB Coder 不支持在归约中使用 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 循环中,不能使用 vararginvarargout

  • 循环索引的类型必须可由目标硬件上的整数类型表示。在生成的代码中使用不需要多字类型的类型。

  • 用于独立代码生成的 parfor 需要工具链方法来编译可执行文件或库。不要更改使代码生成器使用模板联编文件方法的设置。请参阅Project or Configuration Is Using the Template Makefile

  • 要在您的 MATLAB 代码中使用 parfor,您需要 Parallel Computing Toolbox™ 许可证。

有关限制的详尽列表,请参阅 parfor 限制

提示

  • 在以下情况下,请使用 parfor 循环:

    • 您需要一个简单计算的多次循环迭代。parfor 会将这些循环迭代分为若干组,以使每个线程执行一组迭代。

    • 循环迭代需要很长时间才能执行完毕。

  • 当循环中的迭代依赖于其他迭代的结果时,请不要使用 parfor 循环。

    归约是此规则的一个例外。归约变量会将依赖于所有迭代的值累加在一起,但与迭代顺序无关。

  • 输入参数 NumThreads 设置生成的代码中的 OpenMP num_threads() 子句。OpenMP 还支持通过设置环境变量 OMP_NUM_THREADS 或使用 omp_set_num_threads() 来全局限制 C/C++ 中的线程数。有关详细信息,请参阅 openMP 设定。https://www.openmp.org/specifications/

版本历史记录

在 R2012b 中推出