上网搜了好多关于并行计算的东西,现在我就稍微总结下我的一些感受吧。
先区分下并行计算还有分布式计算:
我的理解是:我们本电脑熵进行并行计算,就是多开启几个线程(当然是在多核心的计算机上效果才明显。)
分布式则是:用于多计算机协同工作,即一个主机作为server分配job,其他得到job的client根据主机的要求进行计算,最后将结果传递给server.
首先是了解matlabpool这个线程池(或者说是matlab的工作池),原来我们只启动一个matlab主程序的时候只有一个client在工作,当我们开启这个工作池了以后,会添加多个worker到池子里工作。
首先给大家推荐一个英文的教程:http://people.sc.fsu.edu/~jburkardt/m_src/matlab_parallel/matlab_parallel.html 感觉更全面。
parallel被称作本地并行运算,这种本地的并行运算需要工具箱:MATLAB Parallel Computing Toolbox的支持(查看方法 输入ver命令即可查看)
当然matlab也支持用多台机器进行分布式计算,被称作远程的并行计算。除了上述工具箱外,还需要MATLAB Distributed Computing Server支持。具体关于分布式的计算我没用到,也就不谈了。这里主要说下本地进行并行计算的方法。
环境:至少MATLAB version 2008a or later. 计算机最好核心数大于1的哈,不然所谓的并行就只是并发了。。
首先正常启动matlab,我们所启动的这个matlab进程被称作client,待会将要被开启的多个lab(实验室,我们姑且叫子进程哈)则被称作workers。
所以并行运算其实就是主线程和子线程的一个任务分配和汇总的实现。这种实现过程需要三个基本步骤:
1、需要创建几个workers
2、把任务划分,然后分配给workers
3、整合结果,释放workers
这个过程用matlab写出来就是(这里matlabpool开启的时候我遇到了 java.net.UnknownHostException的错误,本文后面给出解决方案。 )
matlabpool open local 4
your_programme
matlabpool close
记住限制是4,最好就是有几个核心就开几个,这样效率比较高。
并行运算最基本的用法就是采用parfor循环代替for循环,这种循环代替有几点说明:
1、使用parfor前提必须开启matlabpool 否则等于for
2、parfor不能像for一样多层内嵌。。
3、parfor不能调用与上一个循环结果相关的变量,否则就等与for了
total = 0.0; big = - Inf; for i = 1 : n total = total + x(i); big = max ( big, x(i) ); end
for i = 1 : n angle = ( i - 1 ) * pi / ( n - 1 ); t(i) = cos ( angle ); end
上面都可以把for循环改成parfor
但是下面这种依赖前一个循环的结果则不能转换成parfor
还有有用到break continue return 这些类型都不能使用parfor
dx = 0.25; x = zeros (1,n); for i = 2 : n x(i) = x(i-1) + dx; end
经过本人验证,速度确实提升一倍至少。。
这也是我这个学渣最近搞“科研”时没办法遇到的问题,处理一副图像,用了很多算法,最后综合,运行下来三分钟(你妹),已经用了很多优化方法了,然后用线程优化,哈哈哈哈半分钟,已经和别人的一样了。。。
------------------------------------------------------------------------
废话不多说,我在使用matlabpool open 的时候遇到问题:
matlabpool Java exception occurred: java.net.UnknownHostException:
Your_Host_Name at java.net.InetAddress.getLocalHost(Unknown Source)
我google下,在大连理工的BBS上找到了这个问题的解决办法(http://bbs.dlut.edu.cn/nforum/article/LinuxUnix/54089):其实就是local主机名无法识别,我们一般都是用localhost的
我的电脑是Linux 64位,在/etc/hosts这个文件里增加一行我们本地ip和主机名即可:观察上面的错误提示(Your_Host_Name这个每个人电脑都不同)
只要在hosts这个文件加上
127.0.0.1 Your_Host_Name
就可以了。。例如我的提示是Lab001:Lab001我就加入
127.0.0.1 Lab001
然后重启下网络即可:
/etc/init.d/network restart