2017-08-15 8 views
1

私はいくつかの例を実行し、私はいくつかの結果を得ました。私は大きな反復回数を得ましたが、良い結果を得ることができましたが、反復回数が少なければ悪い結果を得ることができます。@parallel対juliaのネイティブループ

私は少しオーバーヘッドがあり、それは絶対に大丈夫だと知っていますが、反復回数が少ないループを連続的な方法よりも並列的に実行する方法はありますか?

x = 0 
@time for i=1:200000000 
    x = Int(rand(Bool)) + x 
end 

7.503359秒(200.00 M配分:2.980ジブ、2.66%のGC時間):私はここに、並列のための良好な結果を得た

x = @time @parallel (+) for i=1:200000000 
    Int(rand(Bool)) 
end 

0.432549秒(241.138 KiBの3.91 Kの割り当て)次の例ではそうではありません。

x2 = 0 
@time for i=1:100000 
    x2 = Int(rand(Bool)) + x2 
end 

0.006025秒(98.97 K割り当て:1.510 MIB)

x2 = @time @parallel (+) for i=1:100000 
    Int(rand(Bool)) 
end 

0.084736秒(3.87 K割り当て:239.122 KiBの)

+2

私は、スレッドを使用することのオーバーヘッドは一定の回数の反復の後にやっていると思っています –

+2

@MauricePerryこれはスレッドではなくマルチプロセッシングです。マルチプロセッシングは、完全に非同期であり、他のコンピュータでもプロセスを持つことができるので、スレッドよりもオーバーヘッドが大きくなります。 @ReDマルチプロセスで利益を得るためには、各プロセスに「十分な」作業が必要です。さもなければ、 'Threads。@ threads'を使ってスレッドを使うべきです。 –

+1

最初にいくつかの用語を教えていただけますか?これは並列処理ではなく、単なる[並行]スケジューリングと定義されている*(cit:)* - ** [並列処理]は**です。並列処理で実行されるすべてのスレッドレベルおよび/または命令レベルのタスクを開始/実行/終了することが保証され、同時に実行されるコードパスの保証された仕上がりを提供する** [並行処理] **このような[並列]実行を可能にするためには、200E + 6個のCPUコアが必要です。ここではなく、** @パラレル**デコレータはCPUを作成しません – user3666197

答えて

0

Q:いくつかのループを実行する方法があります連続的な方法よりも並列処理の方が反復の量が少なくて済みますか?


はい。

1)このすべてが

2を感知得るべきであれば、より多くのリソース(計算するプロセッサ、記憶するメモリ)を取得)は賢くワークフローアレンジ - 活用から、レジスタベースコードから利益を得ること最初のフェッチごとにキャッシュラインのサイズを調整し、可能であれば再利用を展開します(ハードワーク?はい、難しい作業ですが、これを1回支払ったのではなく150+ [ns]を繰り返し支払うのはなぜですか? 〜30 [ns]の待ち時間 - コスト(NUMAが許可する場合)?)。よりスマートなワークフローは、計算結果のアセンブリコード「密度」を増やし、コードを調整して(最適化)スーパースカラープロセッサのハードウェア設計の仕組みをより良くバイパスするために、コードを再設計することを意味します。高度にチューニングされたHPCコンピューティング・ペイロードでは、無駄/プラスのメリットがあります。

3)あなたの最適化コンパイラに精通取得任意のブロックのリソースに&ボトルネック(中央特異点を問わず、ホストのハードウェア独自のソース・オブ・ランダム、IO-デバイスら)

4)をheadbangsを避けます内部オプションと「ショートカット」 - 時には反パターンが長い実行時間をかけて生成される

5)基本オペレーティングシステムの調整から最大限に活用してください。これを行わないと、あなたの最適化されたコードはまだO/Sスケジューラーの待ち行列で待ちます。そして、多くの場合、並列スケジューラーの待ち行列で待ちます。

1

並行して処理することは、常に効率が悪くなります。これは、並行処理を行うと常に同期するためにオーバーヘッドが発生するためです。とにかく、純粋なシーケンシャルコール(1台のコンピュータ、シングルコア)よりも壁の時間に結果を得ることができます。

あなたの番号は驚くべきものであり、原因を見つけました。

まず第一に、すべてのコアを使用することができ、REPL

何が起こった
julia> nworkers 
4 

# original case to get correct relative times 
julia> x = 0 
julia> @time for i=1:200000000 
      x = Int(rand(Bool)) + x 
     end 

7.864891 seconds (200.00 M allocations: 2.980 GiB, 1.62% gc time) 

julia> x = @time @parallel (+) for i=1:200000000 
      Int(rand(Bool)) 
     end 
0.350262 seconds (4.08 k allocations: 254.165 KiB) 
99991471 

# now a correct benchmark 
julia> function test() 
     x = 0 
     for i=1:200000000 
      x = Int(rand(Bool)) + x 
     end 
     end 
julia> @time test() 
0.465478 seconds (4 allocations: 160 bytes) 

に後藤?

最初のテストケースでは、グローバル変数xが使用されています。そして、それはひどい遅いです。ケースは200 000 000倍速の変数にアクセスします。グローバル変数xがちょうど1時間を割り当てられている第二のテストケースで

は、パフォーマンスの低下は、私のテストケースでアカウント

に来ていないので、何のグローバル変数はありません。私はローカル変数を使用しました。ローカル変数の方がはるかに高速です(より良いコンパイラの最適化により)