Matlab并行编程<cellfun & arrayfun>

来源:互联网 发布:linux项目实战 编辑:程序博客网 时间:2024/06/08 14:48

本篇blog针对两个函数cellfun和arrayfun对程序的加速写一些东西,方便大家调的一手好参数。之前的一篇blog《Matlab并行编程方法》在具体实现时可能有问题(下面会讲),而我查到的对Matlab并行的讲解资料也没有写明这个问题。。。所以这里提一下比较实用的matlab并行加速方法,本篇的出现感谢@王小川_Matlab的热心指点。


1. 为什么上一篇对Matlab并行编程有误解?

故事起源于我上篇blog和在微博里提出的问题:4.2中的解决方案,i.e., matlab用parfor时变量循环少的话怎样负载均衡? 上篇我最后yy出来的解决方案比较扯淡,因为这样并不并行都能这么干。所以这里纠正一下这个问题。

事实上,matlab内置了很多并行,所以再手工去用parfor做任务并行有可能是冗余的甚至无利的。尤其循环少(比如parfor i = 1:3)或 循环内部计算量小的时候不要用parfor,原因一是parfor控制单核任务并行(parfor i=1:3只分配任务给3个core),用了parfor之后,每个循环内执行的code只分配给一个core会抑制matlab内置负载均衡机制。





2. 解决方案1:createJob

分配任务给特定cluster。





3. 解决方案2:arrayfun & cellfun


3.1 调1个参数

arrayfun Example:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. y = arrayfun(@(alpha) f1(x,k,alpha), alpha,'UniformOutput',false);  

其中,x是数据,k是定下来的参数,alpha是待调参数,比如alpha = [1,2,3]; 


cellfun Example:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. y = cellfun(@(alpha) f1(x,k,alpha), alpha,'UniformOutput',false);  

这里待定参数alpha是cell,即alpha = {1,2,3}; 

上面两个例子我仅以int做为参数类型的例子,实际上可以用其他类型,调用arrayfun和cellfun的方法相同。


3.2 调两个参数

比如现在有个问题,我要调两个参数:alpha和beta。比较正规的方法是画这么一幅二维图:横坐标alpha,纵坐标beta,(i,j)处的颜色深浅表示取alpha(i),beta(j)时的结果(这个图可以用imagesc作)。而且在取值时也有很多小技巧,比如是均分range取值啦,还是指数分段取值啦etc,这里不详说。

只考虑,当定下来一个备选alpha数组 和 beta数组时, 怎样得到上面这幅图。我们还使用并行的方法。

arrayfun Example:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Lalpha = length(alpha);  
  2. Lbeta = length(beta);  
  3. alpha = reshape(repmat(alpha,Lbeta,1),1,Lalpha*Lbeta);  beta = repmat(beta,1,Lalpha);  
  4. [Dict,AN,~,~,~] = arrayfun(@(alpha,beta) gpnmf(train_s,N_samples,R,RC,alpha,beta,1,1,28),alpha,beta,'UniformOutput',false);  

也就是,用repmat把alpha重复Lbeta次,把beta重复Lalpha次。






4. 性能测试

我们用比较耗时的积分函数进行测试:

T.m

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. N = 10000;  
  2. tic  
  3. for i = 1:N  
  4.     y1 = integral(@(x)1./exp(1+x),0,i);  
  5. end  
  6. toc  
  7.   
  8. tic  
  9. alpha = 1:N;  
  10. y2 = arrayfun(@(a) integral(@(x) 1./exp(1+x),0,a),alpha);  
  11. toc  


结果:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. >> T  
  2. Elapsed time is 16.177388 seconds.  
  3. Elapsed time is 12.904918 seconds.  


感兴趣的朋友还可以测试下不同方法的定积分效率:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. times = 20000;  
  2.   
  3. tic;  
  4. for t = 1:times  
  5.     r1(t) =quadl(@(x) x+1,1,t);  
  6. end  
  7. toc;  
  8.   
  9. tic  
  10. r2 = arrayfun(@(t) Plusx(1,t),1:times);  
  11. toc;  
  12.   
  13. tic  
  14. r3 = arrayfun(@(t) quadl(@(x) x+1,1,t), 1:times);  
  15. toc;  

Plusx.m:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. function [ t ] = Plusx(x,t)  
  2. %PLUSx Summary of this function goes here  
  3. %   Detailed explanation goes here  
  4.   
  5. t =quadl(@(m) m+x,1,t);  
  6. end  
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被撞当天没报警怎么办 90后欠30万债务怎么办 赌博输了钱后悔怎么办 借赌博输了80万怎么办 赌博输了50万怎么办 手机赌博输了钱怎么办 内存卡是扩容卡怎么办 坐了过山车想吐怎么办 坐完摇椅想吐怎么办 玩完过山车想吐怎么办 做了过山车想吐怎么办 坐车后恶心想吐怎么办 太胖了想减肥怎么办 被集资诈骗的人怎么办 教了作业没写怎么办 移动4g网速慢怎么办 小孩装病不去上学怎么办 卖衣服顾客嫌贵怎么办 当顾客说再看看怎么办 读完高中没考上大学怎么办 手抖不会写字了怎么办 字认识写不出来怎么办 八四把衣服发黄怎么办 孩孑在学校被打怎么办 在学校有人打我怎么办 孩子在学校不爱说话怎么办 孩子上幼儿园不和小朋友玩怎么办 遇到有人要打你怎么办 被表白了怎么办神回复 学校要发展我该怎么办 如果有人要打你怎么办 梦见有人要杀我怎么办 如果有人要杀我怎么办 梦到有人要杀我怎么办 感觉有人要杀我怎么办 我很自卑 没自信怎么办 如果在学校被打怎么办 如果有人打我该怎么办 别人要砍我我怎么办 专四两次没过怎么办 3岁宝宝害羞胆小怎么办