Matlab加速循环计算

今天在整理一些MATLAB的parfor加速循环计算的示例。也算是突发奇想,这里整理一些相关的示例,以供参考。

parfor简介

在 MATLAB 中,parfor(parallel for-loop)是一种用于并行执行循环迭代的工具,特别适用于可以独立并行处理的计算任务。使用 parfor 可以显著加速计算密集型程序,尤其是在多核 CPU 或集群环境中。

matlab 复制代码
parfor loopVar = initVal:endVal
    statements
end

与普通 for 循环类似,但要求:

(1)各次迭代之间不能有依赖关系 (即不能互相读写共享变量)。

(2)循环变量必须是整数(不能是向量或结构体等)。

性能提示

(1)避免小任务开销:parfor 有调度开销,适合计算量大的循环。

(2)预分配数组:避免在循环中动态增长数组。

(3)减少数据传输:只传递必要数据到 worker(大矩阵会复制多次)。

(4)使用 spmd 或 parfeval 替代复杂场景:如果 parfor 限制太多。

初步实践

确保 Parallel Computing Toolbox 已安装,并启动并行池:

matlab 复制代码
% 查看当前并行池状态
pool = gcp('nocreate'); % 获取当前池(不自动创建)
if isempty(pool)
    parpool; % 创建默认并行池(通常为本地配置,核心数由设置决定)
end

parfor 要求所有变量属于以下五类之一:

⚠️ 禁止:不同迭代之间通过变量通信(如 A(i) = A(i-1) + 1)。

示例一:蒙特卡洛计算(失败示例)

matlab 复制代码
clear,clc
N = 200;  % 迭代次数减少,但每次很重

tic;
result_for = zeros(N,1);
for i = 1:N
    % 每次做 100,000 次随机采样
    x = rand(1e5, 1);
    result_for(i) = mean(exp(-x.^2));  % 估算 ∫₀¹ e^{-x²} dx
end
time_for = toc;

% parfor
tic;
result_parfor = zeros(N,1);
parfor i = 1:N
    x = rand(1e5, 1);
    result_parfor(i) = mean(exp(-x.^2));
end
time_parfor = toc;

fprintf('for: %.3f s | parfor: %.3f s | 加速比: %.2fx\n', ...
        time_for, time_parfor, time_for/time_parfor);

输出结果:

for: 0.187 s | parfor: 0.224 s | 加速比: 0.84x

普通for循环的速度就比parfor快,parfor没起到真正的加速作用。

示例二:真正适合 parfor 的蒙特卡洛示例

matlab 复制代码
%% 蒙特卡洛估算 ∫₀¹ e^{-x²} dx ≈ 0.746824
clear; clc;

% === 配置参数 ===
N = 20;                     % 迭代次数(每个迭代是一次独立蒙特卡洛实验)
samples_per_iter = 5e6;     % 每次采样数量(越大,单次估计越准)
REPRODUCIBLE = false;       % ← 设置为 true 可强制 for/parfor 结果完全一致(仅用于调试)

% 理论参考值
theoretical = 0.746824132812427;

% 启动并行池(如果需要)
if ~REPRODUCIBLE && isempty(gcp('nocreate'))
    parpool('local');  % 正常模式:让 MATLAB 自动管理随机流
end

%% --- 普通 for 循环 ---
fprintf('Running for loop...\n');
tic;
result_for = zeros(N,1);
if REPRODUCIBLE
    % 调试模式:每次用固定种子
    for i = 1:N
        rng(i);  % 关键:固定种子
        x = rand(samples_per_iter, 1);
        result_for(i) = mean(exp(-x.^2));
    end
else
    % 正常模式:使用全局流(顺序生成)
    for i = 1:N
        x = rand(samples_per_iter, 1);
        result_for(i) = mean(exp(-x.^2));
    end
end
time_for = toc;

%% --- parfor 循环 ---
fprintf('Running parfor loop...\n');
tic;
result_parfor = zeros(N,1);
if REPRODUCIBLE
    % 调试模式:每个 worker 用相同种子
    parfor i = 1:N
        rng(i);  % 与 for 循环相同种子
        x = rand(samples_per_iter, 1);
        result_parfor(i) = mean(exp(-x.^2));
    end
else
    % 正常模式:让每个 worker 使用独立随机流(MATLAB 自动处理)
    parfor i = 1:N
        x = rand(samples_per_iter, 1);
        result_parfor(i) = mean(exp(-x.^2));
    end
end
time_parfor = toc;

%% --- 结果分析 ---
% 1. 检查是否完全一致(仅当 REPRODUCIBLE=true 时应为 true)
is_identical = isequal(result_for, result_parfor);

% 2. 计算统计均值和误差
mean_for    = mean(result_for);
mean_parfor = mean(result_parfor);
err_for     = abs(mean_for - theoretical);
err_parfor  = abs(mean_parfor - theoretical);

% 3. 输出
fprintf('\n=== 结果报告 ===\n');
fprintf('REPRODUCIBLE 模式: %s\n', string(REPRODUCIBLE));
fprintf('结果完全一致: %s\n', string(is_identical));
fprintf('\n理论值: %.9f\n', theoretical);
fprintf('for 均值:    %.9f (误差: %.2e)\n', mean_for, err_for);
fprintf('parfor 均值: %.9f (误差: %.2e)\n', mean_parfor, err_parfor);
fprintf('\nfor 耗时: %.3f s | parfor 耗时: %.3f s | 加速比: %.2fx\n', ...
        time_for, time_parfor, time_for/time_parfor);

输出结果:

理论值: 0.746824133

for 均值: 0.746846070 (误差: 2.19e-05)

parfor 均值: 0.746791349 (误差: 3.28e-05)

for 耗时: 0.841 s | parfor 耗时: 0.381 s | 加速比: 2.21x

这里验证了parfor在一些比较复杂的计算情况下,可以比普通for循环快一些。

以上示例仅供参考。

相关推荐
iCxhust2 小时前
Matlab求解发电机的极限切除角
开发语言·算法·matlab·电力系统
LMT_Lanmantech9 小时前
MATLAB合规管理:如何避免侵权赔偿和审计风险
开发语言·matlab·信息可视化
Evand J10 小时前
【PMSM例程6】永磁同步电机(PMSM)基于增广EKF的d-q轴电感分阶段辨识算法|电机参数估计与误差分析
算法·matlab·电机·ekf
Matlab程序猿10 小时前
【MATLAB源码-第460期】基于matlab的OTFS通信系统SLM峰均比抑制及非线性功率放大器失真与误码性能仿真
开发语言·算法·matlab·slm·otfs
chhttty1 天前
Stateflow状态机建模:数据
matlab·simulink
Matlab程序猿1 天前
【MATLAB源码-第459期】基于matlab的D-H模型与阻尼最小二乘逆运动学的六自由度机械臂五次轨迹规划及动力学前馈PD控制仿真。
人工智能·算法·matlab·d-h建模·六自由度串联机械臂
机器学习之心2 天前
基于CNN-LSTM的轴承剩余寿命预测,MATLAB代码
matlab·cnn·lstm·cnn-lstm·轴承剩余寿命预测
菜鸟~noob2333 天前
【电子战】 第26篇:大气衰减——氧气与水汽吸收【含matlab代码】
开发语言·matlab
菜鸟~noob2333 天前
【电子战】第25篇:自由空间、双射线与菲涅尔区【含matlab代码】
开发语言·算法·matlab
Evand J4 天前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab