10

約 1000 項目のリストに対して実行されるコストのかかる操作を並列化することで、クアッドコア マシンを利用しようとしています。

現在、R の parallel::mclapply 関数を使用しています。

res = rbind.fill(parallel::mclapply(lst, fun, mc.cores=3, mc.preschedule=T))

これは機能します。問題は、生成された追加のサブプロセスが大量のメモリを割り当てなければならないことです:

ここに画像の説明を入力

理想的には、各コアが親 R プロセスから共有メモリにアクセスできるようにして、mclapply で使用するコアの数を増やしても、コアの制限の前に RAM の制限に達しないようにします。

現在、この問題をデバッグする方法について途方に暮れています。各プロセスがアクセスする大規模なデータ構造はすべてグローバルです (現在)。それはどういうわけか問題ですか?

OS の共有メモリの最大設定を 20 GB (使用可能な RAM) に増やしました。

$ cat /etc/sysctl.conf 
kern.sysv.shmmax=21474836480
kern.sysv.shmall=5242880
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.maxprocperuid=512
kern.maxproc=2048

これで問題は解決すると思いましたが、問題は引き続き発生します。

他のアイデアはありますか?

4

3 に答える 3

5

Linux と macosx には、分岐時のコピー オン ライトメカニズムがあります。これは、メモリのページが実際にはコピーされず、最初の書き込みまで共有されることを意味します。 mclapplyは fork() に基づいているため、おそらく (大きな共有データに書き込みをしない限り)、プロセス リスターによって報告されるメモリは実際のメモリではありません。

ただし、結果を収集するとき、マスター プロセスは mclapply の返された結果ごとにメモリを割り当てる必要があります。

あなたをさらに助けるために、私たちはあなたの楽しい機能についてもっと知る必要があります.

于 2013-07-03T09:10:13.467 に答える
1

コピーオンライト機能のおかげで、これは余分なメモリを使用しないと思っていたと思います。リストの要素が大きいと思いますか?おそらく、R が要素を fun() に渡すとき、実際には書き込み時にコピーを使用する代わりに、リスト項目のコピーを作成しています。その場合、次の方法がうまくいく可能性があります。

fun <- function(itemNumber){
  myitem <- lst[[itemNumber]]
  # now do your computations
}
res = rbind.fill(parallel::mclapply(1:length(lst), fun, mc.cores=3, mc.preschedule=T))

またはlst[[itemNumber]]、関数で直接使用します。R/Linux/macos が、関数を作成したときにコピー オン ライトを使用するほどスマートでない場合は、この修正されたアプローチで可能性があります。

編集:リスト内のアイテムを変更していないと思います。その場合、R はデータのコピーを作成します。

于 2014-02-06T18:35:58.177 に答える