Re: [运算] 多层for循环简化 与 GPU加速

楼主: Absolitude (别再睡了起床了爱丽)   2017-12-20 05:04:25
真不好意思,才隔一天就又上来问..
昨天问的东西其实是我要算的东西的第二步,原本他才是瓶颈,但是板上高手一下就解决
了,我现在想不用for处理第一步,也就是求出昨天的atot (m*n,k)
atot中的元素是用一个m*n二维座标(x,y)和三个一组的数字(a1,a2,a3)带入一个函数
f(x,y,a1,a2,a3)求得,三个一组的数字共有k组,所以最后atot的维度是(m*n,k)
https://imgur.com/CTjyecs
程式上先用meshgrid建立座标,再产生k组数字
m=15;
n=19;
k=10000;
[X,Y]=meshgrid(1:m,1:n);
ini=randn(k,3);
为了方便起见这里f就先用sin和多项式来举例
f(x,y,a1,a2,a3)=sin(x+y^2+a1+a2^2+a3^3)
目前想了一个办法是用arrayfun配上reshape
atotpr=arrayfun(@(x,y) sin(x+y^2+ini(:,1)+ini(:,2).^2+ini(:,3).^3),X,Y,'un',0);
atotmid=cell2mat(atotpr);
atot=reshape(atotmid,k,m*n);
这样确实比用三层for loop快很多了,随便试几个m,n,k都快一个数量级以上,不过想知道
有没有更好的方法。另外这样写gpu也没有办法算,matlab的gpu不接受non UniformOutput
,虽然说以目前的速度来看,gpu似乎也不是很有必要了....但还是希望能多学一点
感恩
作者: sunev (Veritas)   2017-12-20 07:50:00
这里xy和a刚好可以拆开,所以atot=bsxfun(@plus,X(:)+Y(:).^2,(ini(:,1)+ini(:,2).^2)')atot=reshape(sin(atot),[m*n k]);另外我印象中arrayfun没有比for-loop快,你可以check一下
楼主: Absolitude (别再睡了起床了爱丽)   2017-12-20 22:11:00
原来可以用(:),我要算的有交叉项,不过刚刚弄出来了感恩!!晚点再看看FOR的
作者: sunev (Veritas)   2017-12-22 16:13:00
真要快还是得用C,不然就是用gpu
作者: profyang (prof)   2017-12-22 20:02:00
2016b以后的matlab不用bsxfun也可以做到2F的事情了直接X(:)+Y(:).^2+(ini(:,1)+ini(:,2).^2)'应该就可以
楼主: Absolitude (别再睡了起床了爱丽)   2017-12-24 01:31:00
对程式语言的本质不了解 C真的一定比MATLAB快吗P大感恩,不过我目前的版本没那么新
作者: LiamIssac (Madchester)   2017-12-24 15:06:00
如果要跟文献拼速度可能需要计较(在同一个环境下) 但如果只是要结果 时间基本不会差到哪(order of 1) 就看程式的写法 那些arrayfun背后也都是循环写成的 只是经过优化而已可以到mathworks的论坛去看看 很多高手在那讨论
作者: profyang (prof)   2017-12-24 18:23:00
用bsxfun的话应该不会比C慢

Links booklink

Contact Us: admin [ a t ] ucptt.com