據說Julia for-loops與矢量化操作一樣快,甚至更快(如果它們使用得當的話)。 我有兩段代碼。這個想法是爲給定的0-1序列找到一個樣本統計量,它是x(在這兩個例子中,我試圖找到一個總和,但是有更復雜的例子,我只是想了解一般意義在我的代碼中的性能陷阱)。第一個看起來像:朱莉婭語。如何擊敗矢量化操作?
S = 2 * sum(x) - n
s_obs_new = abs(S)/sqrt(2 * n)
pval = erfc(s_obs_new)
,第二個是什麼「天真」的經典:
S = 0
for i in eachindex(x)
S += x[i]
end
S = 2 * S - n
s_obs_new = abs(S)/sqrt(2 * n)
pval = erfc(s_obs_new)
使用@benchmark我發現的第一例的運行時間爲11.8毫秒,第二個是38毫秒。
這個例子對我來說非常重要,因爲還有很多其他的地方,矢量化是不可能的,所以我想在devectorized「方式」中進行與矢量化一樣快的計算。
是否有任何想法,爲什麼devectorized代碼可能比矢量化速度慢4倍?類型穩定性是OK,沒有不必要的大的存儲器分配等
用於第一函數的代碼是:
function frequency_monobit_test1(x :: Array{Int8, 1}, n = 0)
# count 1 and 0 in sequence, we want the number
# of 1's and 0's to be approximately the same
# reccomendation n >= 100
# decision Rule(at 1% level): if pval < 0.01 -> non-random
if (n == 0)
n = length(x)
end
S = 2 * sum(x) - n
s_obs_new = abs(S)/sqrt(2 * n)
pval = erfc(s_obs_new)
return pval
二是:
function frequency_monobit_test2(x :: Array{Int8, 1}, n = 0)
# count 1 and 0 in sequence, we want the number
# of 1's and 0's to be approximately the same
# reccomendation n >= 100
# decision Rule(at 1% level): if pval < 0.01 -> non-random
if (n == 0)
n = length(x)
end
S = 0
@inbounds for i in eachindex(x)
S += x[i]
end
S = 2 * S - n
s_obs_new = abs(S)/sqrt(2 * n)
pval = erfc(s_obs_new)
return pval
首先,官方的[性能提示](https://docs.julialang.org/en/stable/manual/performance-tips/)是讀取 –
另一件事,試圖重要的是把'@inbounds @ simd'前面的'for'語句 –
請向我們展示您運行的實際代碼以獲取基準。 –