[討論] 請問有沒有比較快的寫法

作者: 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