提高matlab代码的执行效率,是很多码农们的迫切愿望和需求。最重要的当然是好的代码结构,向量化的语言的高效性是for循环拍马也赶不上的。但是,现实中很多时候我们是需要使用到for循环的,为此可以使用matlab的并行计算来提高代码执行效率。
并行计算的原理就是将代码分配到多个处理器中进行运算。例如8核的机器,就可以同时调动8个处理器来运算。不过为了在运算时你不至于太无聊,还是留下一个给自己做其他事情用吧。
1 parfor运行报错
错误: 不允许向 parfor 的循环变量 "ii" 赋值。
请参阅 MATLAB 中的并行循环,“循环变量”。
parfor ii=1:10
xTemp = ii;
out(ii) = xTemp;
end
disp(xTemp);
就会导致类似的错误,这是因为,parfor的循环顺序是不确定的,这一点和for循环不一样。
2、启动和关闭并行计算功能
如果代码还在调试阶段,可以暂时不关闭matlabpool,反复开关浪费时间得很。另外,matlab关闭后,matlabpool也会自动关闭,所以如果不是海量代码,可以不用关闭的(个人意见,没有实测影响)。
经调试修改为:
CoreNum=7; %调用的处理器个数
% 设定默认的处理器数量
setenv('MATLAB_PARALLEL_DEFAULT_TASK_CPUS', num2str(CoreNum));
% 启动
try
parpool(CoreNum);
disp('MATLAB pool started');
catch
disp('MATLAB pool already started');
end
% 关闭
try
delete(0);
disp('MATLAB pool closed');
catch
disp('MATLAB pool not running');
end
运行结果为:
Starting parallel pool (parpool) using the 'local' profile ...
connected to 7 workers.
MATLAB pool started
3、parfor的使用
将传统的for循环改为parfor循环,就会将循环体作为整体分到到一个个处理器中,从而一次性进行多组运算。在使用parfor时,代码的编写有一些注意事项,最主要的是其中变量的处理。matlab的帮助文档中有详细的描述。
在此,我将摘取一部分重要的加以说明并举例。
在parfor中,变量不再是随心所欲的使用,有着其自己的分类。在parfor运行时,我们经常会遇到这样的错误“ Error: The variable xxx in a parfor cannot be classified.”说的就是变量xxx不能被正常划分到正确的类别中。
parfor变量一共分为5类,每一类的定义和用途就不说了,看一眼就明白。需要注意的是以下几点:
(1)循环变量
循环变量在循环体中的使用一定要具有独立性,循环体之间不相关。例
a(i)=a(i-1)*temp;是不行的。
(2)sliced 变量(一般是数组,被各个处理器分割成一个个slice)
slice变量在一个循环体内只能出现一个slice,简单说就是一个循环体内只能出现slice数组的一个元素。例
a(i)=temp1;
a(i+1)=temp2;
是不行的。
另外,slice变量的下标一定要连续,例
a(2*i)=temp;
是不行的。
(3)临时变量
matlab使用变量的一个好处是不需要预定义。但是在使用parfor时,这会弄混sliced变量和临时变量。由于临时变量不需要有sliced变量的限制,使用更自由,因此一定要区分开。方法是在parfor中对临时变量进行预定义。例
parfor i=1:10
b=zeros(1,4);
for j=1:4
b(i)=i+1;
end
a(i)=b; %a是sliced变量
end
基本上注意到这几个问题就能正常运行parfor了。