MATLAB parfor简介

文章介绍了MATLAB中的parfor循环用于并行计算的场景,适合长时间循环迭代和矢量化计算。当循环迭代相互独立时,parfor能提升效率,但高并行开销或短迭代时可能适得其反。示例展示了低并行开销时的性能提升和高并行开销时的效率下降。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MATLAB parfor循环简介

一、决定何时使用parfor循环

如果有以下情况,考虑采用parfor循环:

  • 一些需要执行很长时间的循环迭代。在这种情况下,workers可以同时执行长迭代。
  • 简单计算的多次循环迭代,例如蒙特卡罗模拟或参数扫描。parfor将循环迭代分成几组,每个worker执行总迭代次数的一部分。

如果有以下情况,parfor循环可能没有用:

  • 以矢量化输出的for循环。一般来说,如果想让代码运行得更快,首先尝试对其进行矢量化,矢量化代码能够受益于许多底层MATLAB库的多线程特性所提供的内置并行性。但是,如果有矢量化代码并且只能访问本地的worker,那么 parfor-loops 可能比 for-loops 运行得慢。
  • 只需要很短执行时间的循环迭代。在这种情况下,并行开销主导了计算。

当循环中的迭代取决于其他迭代的结果时,不能使用parfor-loop 。每次迭代都必须独立于所有其他迭代。

二、低并行开销的例子

该示例计算了矩阵的谱半径,并将一个for循环转换为parfor循环。了解如何测量由此带来的加速,以及并行池中的worker有多少数据量传入传出。

tic
n = 200;
A = 500;
a = zeros(n);
for i = 1:n
    a(i) = max(abs(eig(rand(A))));
end
toc

以上for循环经历了31.935373秒

tic
ticBytes(gcp);
n = 200;
A = 500;
a = zeros(n);
parfor i = 1:n
    a(i) = max(abs(eig(rand(A))));
end
tocBytes(gcp)
toc

以上parfor循环经历了10.760068秒

当前示例的并行开销较低,并且受益于parfor-loop的转换。

三、高并行开销的例子

此示例编写一个循环来创建一个简单的正弦波。此循环没有很多迭代,执行时间不长,执行速度的提高不显著。此示例具有高并行开销,并且无法从转换为parfor-loop 中获益。

tic
n = 1024;
A = zeros(n);
for i = 1:n
    A(i,:) = (1:n) .* sin(i*2*pi/1024);
end
toc

以上for循环经历了0.012501秒

tic
ticBytes(gcp);
n = 1024;
A = zeros(n);
parfor (i = 1:n)
    A(i,:) = (1:n) .* sin(i*2*pi/1024);
end
tocBytes(gcp)
toc

以上parfor循环经历了0.743855秒

注意到串行loop的运行时间比四个worker的并行loop运行时间要小得多,原因是数据的传输比前面的例子要多得多

### MATLAB `parfor` 并行循环语法详解 #### 一、基础语法 `parfor` 是用于执行并行计算的循环结构,在多核处理器或多台计算机上加速代码运行。其基本形式如下: ```matlab parfor i = istart:istep:iend % 循环体内的命令序列 end ``` 其中,`i` 表示循环变量;`istart`, `istep`, 和 `iend` 定义了迭代范围[^1]。 #### 二、注意事项 - **初始化开销**:首次使用 `parfor` 可能会有额外延迟来启动必要的资源分配过程。因此建议在同一会话中重复利用已建立的工作池以减少等待时间[^2]。 - **依赖关系处理**:为了确保线程安全性和正确性,应避免在不同迭代之间存在相互依存的数据访问模式。具体来说就是防止出现读取未赋值或正在被其他 worker 修改中的共享内存区域的情况。 #### 三、简单例子展示如何运用 `parfor` 下面给出一段简单的代码片段用来对比串行版本 (`for`) 和并行化后的版本(`parfor`) 的性能差异: ```matlab % 创建一个较大的数组作为测试对象 A = rand(1000, 1000); tic; % 开始计时 B_for = zeros(size(A)); for rowIdx = 1:size(A, 1) B_for(rowIdx,:) = A(rowIdx,:).^2; end timeForLoop = toc; % 结束计时并记录耗时 tic; % 再次开始新的计时周期 C_parfor = zeros(size(A)); parfor colIdx = 1:size(A, 2) C_parfor(:,colIdx) = A(:,colIdx).^2; end timeParforLoop = toc; % 记录此次结束时刻距离上次 tic 所经过秒数 disp(['Time taken by for loop is ', num2str(timeForLoop), ' seconds']); disp(['Time taken by parfor loop is ', num2str(timeParforLoop), ' seconds']); ``` 这段脚本创建了一个大矩阵,并分别用常规 `for` 循环和 `parfor` 来对其元素平方运算。最后打印两者所需的时间以便比较效率提升情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值