このJulia関数は非常に非効率的であるようです(Juliaのウォームアップ後でも、同等のPythran / C ++コードよりも1桁遅い)...
function my_multi_broadcast(a)
10 * (2*a.^2 + 4*a.^3) + 2 ./ a
end
arr = ones(1000, 1000)
my_multi_broadcast(arr)
正しく書いていないだけだと思います…ジュリアでこんな「マルチ放送」をどうやってスピードアップできるのでしょうか?私はループを費やす必要がないと思います/願っています...
ありがとうございました!私のセットアップでは、Pythranソリューション(インプレースおよびアウトオブプレース)は、(OpenMPなしで)1.5〜2倍高速です。JuliaでSIMD命令をアクティブにする方法はありますか?または、そのようなCPU計算を高速化する別の方法はありますか?
Pythonコード:
from transonic import jit
@jit
def broadcast(a):
return 10 * (2*a**2 + 4*a**3) + 2 / a
@jit
def broadcast_inplace(a):
a[:] = 10 * (2*a**2 + 4*a**3) + 2 / a
@simd
提案後に編集する@simd
そのままでは機能しないようです。つまり、行の先頭に追加するだけでは機能しません。
ERROR: LoadError: LoadError: Base.SimdLoop.SimdError("for loop expected")
Stacktrace:
[1] compile(::Expr, ::Bool) at ./simdloop.jl:54
[2] @simd(::LineNumberNode, ::Module, ::Any) at ./simdloop.jl:126
[3] include at ./boot.jl:317 [inlined]
[4] include_relative(::Module, ::String) at ./loading.jl:1044
[5] include(::Module, ::String) at ./sysimg.jl:29
[6] exec_options(::Base.JLOptions) at ./client.jl:231
[7] _start() at ./client.jl:425
forループを拡張する必要があると思いますが、そうすると、コードは(i)読みにくくなり、(ii)次元から独立しなくなります。
単純なPython / NumpyコードがPythranでJuliaよりも速く加速できる場合があるようです(Juliaでこれを加速する方法があり、将来のJuliaバージョンでこれが解決される可能性がある場合を除く)。面白い...
次のようなすべての操作をブロードキャストします。
julia> function my_multi_broadcast2(a)
@. 10 * (2*a^2 + 4*a^3) + 2 / a
end
my_multi_broadcast2 (generic function with 1 method)
違いは、2つは10 * (2*a.^2 + 4*a.^3) + 2 ./ a
ブロードキャストされないため、実際にはブロードキャストフュージョンを利用しないことです。*
+
書くこと@. 10 * (2*a^2 + 4*a^3) + 2 / a
はと同等10 .* (2 .* a.^2 .+ 4 .* a.^3) .+ 2 ./ a
です。
そしてここにパフォーマンスの比較があります
julia> @btime my_multi_broadcast($arr);
58.146 ms (18 allocations: 61.04 MiB)
julia> @btime my_multi_broadcast2($arr);
5.982 ms (4 allocations: 7.63 MiB)
約10倍のスピードアップが得られるので、Pythran / C ++と比較してどうですか?
最後に、次のように記述して、そのarr
場で変更できる場合は注意してください。
julia> function my_multi_broadcast3(a)
@. a = 10 * (2*a^2 + 4*a^3) + 2 / a
end
my_multi_broadcast3 (generic function with 1 method)
julia> @btime my_multi_broadcast3($arr);
1.840 ms (0 allocations: 0 bytes)
これはさらに高速で、割り当てはゼロです(そのarr
場で変更するのか、新しい配列を作成するのかわからないので、両方のアプローチを示します)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加