2

私はこのコードを使用しています:

library(parallel)
cl <- makeCluster( detectCores() - 1)
clusterCall(cl, function(){library(imager)})

次に、次のようなラッパー関数があります。

d <- matrix  #Loading a batch of data into a matrix
res <- parApply(cl, d, 1, FUN, ...)
# Upload `res` somewhere

8 コア (4 コア、ハイパースレッディング) のノートブックでテストしました。50,000 行、800 列のマトリックスで実行したところ、完了するまでに 177.5 秒かかりました。ほとんどの場合、7 つのコアはほぼ 100% に保たれ (トップによると)、最後の 15 分間はそのままでした。結果を組み合わせていたと思います。によるとsystem.time()、ユーザー時間は 14 秒なので一致します。

現在、私は 36 コアの c4.8xlarge である EC2 で実行していますが、ほぼすべての時間を 1 つのコアだけで 100% 費やしています。より正確には:すべてのコアが使用されている約10〜20秒のバーストがあり、次に100%のコアが約90秒(Rによって使用されている)、次に約45秒の他のものがあります(結果を保存し、データの次のバッチをロードします)。40,000 行、800 列のバッチを実行しています。

top によると、長期的な負荷平均は 5.00 前後で推移しています。

これは合理的に思えますか?または、R の並列処理が通信のオーバーヘッドにより多くの時間を費やすポイントはありますか?たとえば、16 コアに制限する必要があります。ここに経験則はありますか?

参考:CPUスペック 「Linux 4.4.5-15.26.amzn1.x86_64(amd64)」を使用しています。R バージョン 3.2.2 (2015-08-14)

更新: 16 コアで試しました。最小データの場合、実行時間は 13.9 秒から 18.3 秒に増加しました。中規模のデータの場合:

With 16 cores:
   user  system elapsed 
 30.424   0.580  60.034 

With 35 cores:
   user  system elapsed 
 30.220   0.604  54.395 

つまり、オーバーヘッド部分は同じ時間かかりましたが、並列ビットはコア数が少ないため時間がかかり、全体的に時間がかかりました。

mclapply()コメントで提案されているように、も使用してみました。それは少し速いように見えました (私が試した特定のテスト データでは 330 秒と 360 秒のようなものです) が、それは私のノートブック上であり、他のプロセスや過熱が結果に影響を与える可能性があります。だから、私はまだそれについて結論を出していません。

4

2 に答える 2

2

有用な経験則はありません。並列タスクに最適なコアの数は、そのタスクによって完全に決まります。より一般的な議論については、グスタフソンの法則を参照してください。

コードで見られるシングル コアの割合が高い部分は、おそらくアルゴリズムの最終フェーズ (「結合」フェーズ) に由来します。ここでは、並列結果が 1 つのデータ構造に照合されます。これは並列計算フェーズをはるかに超えているため、実際にはコア数を減らすことが有益であることを示している可能性があります。

于 2016-09-13T10:19:54.967 に答える
2

R での並列計算に関するこの素晴らしいリソースをご存じない場合は、Norman Matloff の最近の本Parallel Computing for Data Science: With Examples in R, C++ and CUDAを読むと非常に役立つかもしれません。強くお勧めします (CS のバックグラウンドからではなく、多くのことを学びました)。

この本はあなたの質問に深く答えています (具体的には第 2 章)。この本は、並列プログラムのボトルネックにつながるオーバーヘッドの原因の概要を示しています。

あなたの質問に暗黙のうちに部分的に答えるセクション2.1を引用します。

並列プログラミングには、主なパフォーマンスの問題が 2 つあります。

通信オーバーヘッド: 通常、プロセス間でデータをやり取りする必要があります。これには時間がかかり、パフォーマンスが大幅に低下する可能性があります。さらに、すべてのプロセスが一度に同じデータにアクセスしようとすると、プロセスが互いに干渉する可能性があります。同じ通信チャネル、同じメモリ モジュールなどにアクセスしようとすると、衝突する可能性があります。これは、速度のもう 1 つの樹液です。粒度という用語は、大まかに言うと、オーバーヘッドに対する計算の比率を指すために使用されます。大粒度または粗粒度のアルゴリズムには、オーバーヘッドがそれほど問題にならないほど大きな計算チャンクが含まれます。きめの細かいアルゴリズムでは、オーバーヘッドを可能な限り回避する必要があります。

^ オーバーヘッドが高い場合、目前の問題のコア数を減らすと、合計計算時間が短くなる可能性があります。

負荷分散: 前の章で説明したように、プロセスに作業を割り当てる方法に注意しないと、他のプロセスよりも多くの作業を一部のプロセスに割り当てるリスクがあります。これにより、実行の最後に一部のプロセスが非生産的なままになるため、パフォーマンスが低下しますが、実行すべき作業はまだ残っています。

すべてのコアを使用しない場合はいつですか? RAM で 100 ~ 200 GB のデータに相当するデータに対して R で毎日 cronjobs を実行した私の個人的な経験からの 1 つの例では、複数のコアが実行されてデータのブロックを処理します。 20 ~ 30 個のコアを使用するよりも高速です。主な理由は、子プロセスのメモリ要件でした (特定の数の子プロセスが動作した後、メモリ使用量が高くなり、処理が大幅に遅くなりました)。

于 2016-10-07T00:56:05.357 に答える