[讨论] 请问有没有比较快的写法

楼主: sean791121 (尚恩)   2015-05-28 23:31:39
indx是一个index的向量,A和B是矩阵,我想把B中的某些元素放到A内
举例来说:
for i = 2:10000
A(idx(i),idx(1:i-1))=B(idx(i),idx(1:i-1))
end
请问有比较快的写法吗?
楼主: sean791121 (尚恩)   2015-05-28 23:34:00
因为循环内的每一圈都处理不同大小的空间,所以不行用parfor 求比较快的方法
作者: sunev (Veritas)   2015-05-28 23:59:00
sub2ind
楼主: sean791121 (尚恩)   2015-05-29 00:33:00
意思是用两层for然后用sub2ind找位置吗?其实用一层loop也可以,我加速了快两倍,可是和预期的速度还是有落差,请问还有更快的写法吗?
作者: celestialgod (天)   2015-05-29 00:56:00
我测试了一下,A,B如果都是两万乘两万的矩阵idx是长度10000,也只要2.345秒而已这样还是不够快吗?
楼主: sean791121 (尚恩)   2015-05-29 01:26:00
cpu是i5 跑出来大概1.X秒看文献 Pentium 4 跑这段code再加上很多有的没的 1秒我猜文献应该有用更快的方法 or我的算法太烂了对不起,忘记说明A和B都是sparse的A(sub_index)=B(sub_index)是不是比较慢呢?因为matlab建议使用sparse(I,J,V,m,m)
作者: celestialgod (天)   2015-05-29 02:16:00
文献也是用MATLAB? 而且你矩阵大小多少?http://pastebin.com/D2jJSkRk MATLAB档案http://pastebin.com/JaUSthpX C++档案我稍微试了一下,循环应该是MATLAB中最快的了要再加速就要靠MEX了,还不能复制input才做得到环境: MATLAB 2015a, windows 7 64bit,i7-3770K@4.4GHz
楼主: sean791121 (尚恩)   2015-05-29 05:18:00
文献也是用MATLAB,我的矩阵5000乘5000谢谢你提供方法,我会研究一下的想请问您 为什么matlab的速度会与C差这么多?因为MATLAB都会先判断一些性质(矩阵、函数)的关系吗?对不起,我跑你的C++档会出现bug,code没问题呀XD
作者: sunev (Veritas)   2015-05-29 09:21:00
celestialgod太厉害了,可以想出这么多写法。我实际用c大给的code稍稍profile了一下。发现实际做出idx的方法(2~4),其实在真正assign的那行A(idx)=B(idx)并没有比循环省下太多时间,所以算出idx的时间成本反而盖过了直接assign的效益。另外method 3中,应为triu(....,1),下面的 2:end可以去掉
作者: celestialgod (天)   2015-05-29 09:27:00
我昨天没有想到一个可以直接产生idx的方法
作者: sunev (Veritas)   2015-05-29 09:27:00
如果把(idx3>0)改成triu(true(mat_size,mat_size),1)会快一点,但仍比不上循环。
作者: celestialgod (天)   2015-05-29 09:29:00
我等等试试看,感谢
作者: sunev (Veritas)   2015-05-29 09:30:00
另外我的经验是,sparse在这种大量不规则assign的情况下
作者: celestialgod (天)   2015-05-29 09:31:00
原PO,我的c code,自己跑是没问题的,我编译的指令也在上面,你可能需要再研究一下。
作者: sunev (Veritas)   2015-05-29 09:32:00
速度是慢了点,因为要一直改non-zero element很麻烦。所以官方才会建议用sparse一起解决。
作者: celestialgod (天)   2015-05-29 09:34:00
这里sparse matrix不会比较快原po, c的速度会快本来就不意外.....这题只要想到怎样产生(1, 1, 2, 1, 2, 3, 1, 2, 3,4, 1, 2, 3, 4, 5,... )的方法就会很快(不用矩阵取上三角... 这个会用到太多内存还是会慢)
作者: sunev (Veritas)   2015-05-29 09:55:00
没错,不过true只要1byte,所以还好。XD刚发现不错的写法A(idx,idx)=tril(B(idx,idx),-1)+triu(A(idx,idx));但如果idx很大,B(idx,idx)这个sparse有可能会吃很多内存
作者: celestialgod (天)   2015-05-29 10:57:00
我测试的结果是assign反而比较久我算idx的时间大概0.5秒,assign要花2.1秒我也试着用gpuArray去算idx,但是还是卡在assign
作者: sunev (Veritas)   2015-05-29 11:04:00
你矩阵是5000*5000,idx长度是10000吗?这样你矩阵还会是 "sparse" 吗?
作者: celestialgod (天)   2015-05-29 11:08:00
5000*5000, 10000也只占0.04%..不过我用15000*15000我错了XD,idx长度10000,要改将近5000万个值
作者: sunev (Veritas)   2015-05-29 11:12:00
我是问原作者啦。不确定他想加速到什么程度,所以想确定问题的size
作者: celestialgod (天)   2015-05-29 11:13:00
刚刚有发现XDD如果assign的成本比算idx的成本还贵,这问题无解只能用C去更动矩阵的值才会快上不少
作者: sunev (Veritas)   2015-05-29 11:15:00
再回楼上,我的意思不是assign比算idx久,而是一行assign比循环assign省不了多少时间,而算idx会超过省下的时间。
作者: celestialgod (天)   2015-05-29 11:17:00
喔喔,我懂了一行assign省下的时间没有比算idx的时间短
楼主: sean791121 (尚恩)   2015-05-29 12:54:00
对不起,K大概4800,谢谢两位的帮忙

Links booklink

Contact Us: admin [ a t ] ucptt.com