パッケージは、ループdoParallel
で参照されるワーカーに変数を自動エクスポートします。foreach
それをしたくない場合は、foreach
「.noexport」オプションを使用して、特定の変数を自動エクスポートしないようにすることができます。しかし、私があなたを正しく理解していれば、あなたの問題は、R が後でこれらの変数の一部を複製していることです。これは、単一のマシン上の複数のプロセスで発生しているため、通常よりもさらに問題です。
R が変数の複製を作成しないように変数を宣言する方法はありません。コピーが作成されないように、問題のある変数をパッケージのようなオブジェクトに置き換えるかbigmemory
、重複をトリガーしないようにコードを変更する必要があります。tracemem
オブジェクトが複製されるたびにメッセージが出力されるため、この関数を使用すると役立ちます。
ただし、ワーカーが必要とするデータを減らすことで、問題を回避できる場合があります。これにより、各ワーカーにコピーする必要があるデータの量が減り、メモリ フットプリントも減少します。
以下は、ワーカーに必要以上のデータを与える典型的な例です。
x <- matrix(1:100, 10)
foreach(i=1:10, .combine='c') %dopar% {
mean(x[,i])
}
行列x
はforeach
ループ内で参照されるため、各ワーカーが列のサブセットのみを必要とする場合でも、各ワーカーに自動エクスポートされます。最も簡単な解決策は、列インデックスではなく、行列の実際の列を反復処理することです。
foreach(xc=x, .combine='c') %dopar% {
mean(xc)
}
ワーカーに転送されるデータが少なくなるだけでなく、実際には各ワーカーがメモリ内に一度に 1 つの列を持つだけで済みます。これにより、大規模な行列のメモリ フットプリントが大幅に削減されます。ベクトルは依然として複製される可能性がありますxc
が、 よりもはるかに小さいため、それほど害はありませんx
。
この手法は、 や などの「雪から派生した」関数を使用する場合にのみ役立ち、をdoParallel
使用する場合には役立ちません。この手法を使用すると、使用時にループが少し遅くなる可能性があります。これは、すべてのワーカーが行列を無料で取得するためです。では、ワーカーが既に行列全体を持っているのに、なぜ列を移動するのでしょうか? ただし、Windows ではを使用できないため、この手法は非常に重要です。parLapply
clusterApplyLB
mclapply
mclapply
x
doParallel
mclapply
重要なことは、ワーカーが作業を実行するために本当に必要なデータは何かを考え、可能であればそれを減らすようにすることです。iterators
またはパッケージの特別なイテレータを使用してそれを行うことができるitertools
場合もありますが、アルゴリズムを変更することでそれを行うこともできます。