Matlab中如何让CPU使用率达100%?parfor仅50%占用问题咨询
Matlab parfor循环CPU占用率50%问题解答
结合给出的硬件配置(4物理核心、支持超线程共8逻辑线程的CPU),针对三个问题逐一说明:
问题1:是否当前仅能调用4个CPU核心?
- 不是硬件层面只能调用4个核心,是Matlab并行计算工具箱的默认配置通常按物理核心数分配Worker,默认配置下Worker数为4,每个Worker跑满1个物理核心时,系统总CPU占用约50%,属于默认配置下的正常现象。
- 补充:如果你的自定义函数包含大量Matlab原生的大规模矩阵运算,这类运算本身已经做了多线程优化,强行开超线程的逻辑核心会出现资源争抢,实际计算速度反而可能下降,不是Worker数越多越好。
问题2:是否存在对应命令可开启全部CPU核心用于计算?
- 存在。首先可以用
gcp('nocreate')命令查看当前已启动并行池的Worker数;如果没有启动并行池,执行parpool(N)即可启动N个Worker的并行池,要占满8个逻辑线程就执行parpool(8)。 - 如果需要永久修改默认Worker数,在Matlab主页点击「并行」-「并行池首选项」,把默认的Worker最大数量改成你需要的数值即可,数值上限为CPU逻辑线程总数。
- 注意:如果启动时提示Worker数超出许可限制,是当前Matlab版本的并行计算工具箱许可有授权数量限制,需要对应调整许可。实际测试中,对包含大量原生矩阵运算的科学计算任务,Worker数设为等于物理核心数(4)时,计算效率通常比开8个逻辑核心高20%左右,可以自己跑基准测试选最优值。
问题3:parfor循环的编写方式是否会影响CPU占用率?
- 会,你当前的代码写法存在明显拉低CPU占用的问题:
- parfor放在两层for循环的最内层,每次外层循环迭代时,都会触发并行任务调度、Worker间数据传输的额外开销,调度间隙CPU会处于闲置状态,直接拉低平均占用率。
- parfor内的变量没有做显式分类,Matlab需要在每次启动内层parfor时,给所有Worker重复拷贝全量输入数据,数据传输阶段Worker无计算负载,CPU占用会掉下来。
- 如果自定义的
Getdataz、Solve_CC_rhoE_zGau、fullfidelity函数内部存在串行IO操作、非线程安全的第三方库调用、UI弹窗等阻塞逻辑,会导致部分Worker挂起等待,整体CPU占用也会偏低。
- 优化方向:把parfor移到最外层,把多层循环的参数提前平铺成一维列表,只做一次并行调度,减少调度和数据传输开销,参考优化后的代码框架:
n = 5; d = 2^n; r0 = [2 3]; m = d^2; delta0 = 0:0.05:0.5; ave = 50; % 提前生成所有参数组合,把parfor放到最外层 [j_grid, k1_grid, i_grid] = ndgrid(1:length(r0), 1:length(delta0), 1:ave); total_iter = numel(j_grid); FdRho_all = zeros(total_iter,1); delta_all = zeros(length(delta0),1); FdRho_out = zeros(length(delta0), ave); tic % 提前启动并行池,避免循环内反复启动 if isempty(gcp('nocreate')) parpool(4); % 可自行对比4物理核心/8逻辑核心的实际计算速度选最优值 end parfor iter = 1:total_iter j = j_grid(iter); k1 = k1_grid(iter); i = i_grid(iter); delta = delta0(k1); r = r0(j); [Pauli,y,rhoT,noiseT] = Getdataz(d,n,r,m,s,delta); [rhoE,noiseE] = Solve_CC_rhoE_zGau(n,r,m,s,Pauli,y,noiseT,delta); rhoE = rhoE/trace(rhoE); FdRho_all(iter) = fullfidelity(rhoT,rhoE); end % 循环结束后统一整理结果 for k1 = 1:length(delta0) delta_all(k1,1) = delta0(k1); idx = k1_grid == k1; FdRho_out(k1,:) = FdRho_all(idx); end out.delta = delta_all; out.FdRho = FdRho_out; toc
排查提示:如果调整Worker数、优化循环结构后CPU占用仍然上不去,打开任务管理器查看CPU核心负载分布,如果出现单核心跑满、其余核心闲置的情况,优先检查自定义函数内部是否存在waitbar进度条、文件读写锁、全局变量竞争这类阻塞逻辑,删掉对应阻塞代码即可。
内容的提问来源于stack exchange,提问作者karry
相关产品推荐
相关产品推荐

