プロセス並列化+リダクション演算による配列の和の計算 [Julia]
配列要素の総和を求めるような演算は,数値計算においてしばしば表れる.たとえば Julia で書かれた次のようなコードがあるとする.
# 配列 a, b の確保 sum_a = zero(eltype(a)); sum_b = zero(eltype(b)); for j in 1:N for i in 1:M sum_a += a(i,j); sum_b += b(i,j); end end
このようなコードを並列化する場合,リソース(メモリ)の競合を避けるための対策が必要となる.たとえば,C++/OpenMP でスレッド並列化する場合は,reduction
指示子があるので比較的簡単に並列化できる.
// 配列 a, b の確保 double sum_a = 0.0; double sum_b = 0.0; #pragma omp parallel for reduction(+:sum_a, sum_b) for ( int i = 0; i < M; i++) { for ( int j = 0; j < N; j++ ) { sum_a += a[i][j]; sum_b += b[i][j]; } }
残念ながら,現時点で Julia のスレッド並列にはリダクションが実装されていない.一時変数やアトミック操作を使う手もあるが,なるべく簡単に並列化したい.幸いプロセス並列にはリダクションが実装されているので,上のコードは次のようにすることでプロセス並列化できる.
using Distributed addprocs(); # 複数プロセス立ち上げ # 配列 a, b の確保 sum_a, sum_a = @distributed (+) for j in 1:N sum_a = zero(eltype(a)); sum_b = zero(eltype(b)); for i in 1:M sum_a += a(i,j); sum_b += b(i,j); end [sum_a, sum_b]; end