julia 中內建函式與巢狀迴圈的效率

2022-08-27 08:06:11 字數 2541 閱讀 1124

前面做寬動態成像(前面的文章)時遇到了執行瓶頸,主要是在計算量上,要計算的式子如下:

\[\begin

i_(x,y)=\sum_^\sum_^b_(x,y)u(x-rx_,y-ry_)i_}(x,y)

\end

\]而bij(x,y)的計算也有求和運算:

\[\begin

b_(x,y)=\frac)^2 } + \frac)^2 } \right) }}

^\sum_^e^)^2 } + \frac)^2 } \right) } }

\end

\]做實驗的時候設定m=20,n=15,h,w分別為597,397,結果一迴圈就回不來了。。。(對julia的迴圈優化也是充滿信心)

後面試了下用空間換效率的辦法:增加一維儲存m×n個的矩陣,然後用內建求和,發現提公升明顯。。。

...

bm=zeros(h,w,m*n)*0.

x=collect(1:w)'.-zeros(h)

y=collect(1:h).-zeros(w)'

for pn=1:n

for pm=1:m

bm[:,:,pn+(pm-1)*n]=1./exp( (x-mncenmatrix[pm,pn,1]).^2/(2*sigmax^2) + (y-mncenmatrix[pm,pn,2]).^2/(2*sigmay^2) ) .*

convert(array,epsilon.>map(max,abs(x-mncenmatrix[pm,pn,1]),abs(y-mncenmatrix[pm,pn,2])))

endendbm=bm./sum(bm,3)

for pn=1:n

for pm=1:m

reti[:]=reti[:]+(bm[:,:,pn+(pm-1)*n].*ilm[:,:,pn+(pm-1)*n])[:]

endend...

然後就想看看內建函式和巢狀函式差了多遠:

h,w=900,800

c=300

m=rand(h,w,c)

n=rand(h,w)

function matrixsum!(m::array,ret::array)

h,w,c=size(m)

for pw=1:w

for ph=1:h

for pc=1:c

ret[ph,pw]=ret[ph,pw]+m[ph,pw,pc]

endend

endend

@time n1=sum(m,3)

@time matrixsum!(m,n)

返回:

# i3 cpu 530 @ 2.93ghz × 4 

0.687958 seconds (19 allocations: 5.494 mb)

2.001088 seconds (6.04 k allocations: 246.260 kb)

對這結果甚是無語。。。分配了5.5mb也比你跑得快,是分配次數多限制了提公升?難道這樣的巢狀寫法還可以大幅優化?(我一直以為這就是記憶體最簡寫法了)

突然想到訪問次序有些關鍵,於是調整了下:

h,w=900,800

c=300

m=rand(h,w,c)

n=rand(h,w)

function matrixsum!(m::array,ret::array)

h,w,c=size(m)

for pc=1:c

for pw=1:w

for ph=1:h

ret[ph,pw]=ret[ph,pw]+m[ph,pw,pc]

endend

endend

@time n1=sum(m,3)

@time matrixsum!(m,n)

返回:

# 首次執行

0.879469 seconds (193.28 k allocations: 13.598 mb)

0.787520 seconds (6.47 k allocations: 269.166 kb)

# 再次執行

0.609809 seconds (19 allocations: 5.494 mb)

0.788194 seconds (6.04 k allocations: 246.260 kb)

就內建函式來看,記憶體分配的次數並沒有太多的決定時間消耗;

就內建函式與迴圈巢狀對比來看,剛才是訪問順序的問題。

那麼記憶體為什麼分配了那麼多次呢?

突然想到julia的動態編譯機制,於是拿出來單獨執行了次:

julia> @time matrixsum!(m,n)

0.765424 seconds (4 allocations: 160 bytes)

看來是這樣的。

julia 的優化確實做得不錯,幾乎達到了極致;

訪問順序很關鍵;

分配次數並不一定會是瓶頸。

julia常用矩陣函式 Julia中的函式

如何宣告函式 julia為我們提供了一些編寫函式的方法。第乙個需要function和end關鍵字 function sayhi name println hi name,it s great to see you endfunction f x x 2end 我們可以像這樣呼叫已宣告的函式 sayh...

python中的迴圈巢狀 函式

1.while巢狀迴圈格式0 定義計數器1 while 條件1 執行滿足條件1的 定義計數器2 while 條件2 執行滿足條件2的 計數器2 1 計數器1 1 2.end可以代替換行 print 函式在python中預設換行 print nihao end 列印的時候不換行 print nihao...

js中for迴圈巢狀

首先我們的for迴圈單個就是我們將內容全部輸出出來執行的條件 1.首先宣告初始值 2.設定條件 3.執行 塊 4.執行i 如下,測試10 js的for迴圈巢狀例子 1.宣告初始值 2.設定條件 3.執行外圈 4.外圈執行一次外邊迴圈全部 5.外圈執行 塊後,執行 i 如果繼續執行還是這個邏輯向下接著...