2012-01-15 33 views
2

私は、インデックスに基づいて値を検索するために使用する関数を持っています。値には計算に時間がかかりますので、ParallelMapでそれを実行したいと思います。また、インデックスに基づいて式のリストを返す同様の関数を参照しています。変数/関数定義をParallel(ParallelMapなど)で設定するにはどうすればよいですか?

しかし、一見合理的な方法ですべてを設定すると、私はいくつかの非常に奇妙な動作を見ます。まず、関数が非常にゆっくりではあるものの、動作するように見えます。しかし、大きなインデックスの場合、Taskmanglerのプロセッサアクティビティは、Mathematicaのすべてのインスタンスが見かけ上不活性である長期間(つまり2〜4分)、完全にゼロに留まります。次に、CPU使用率が少しでも低下すると、結果が表示されます。これはMathematicaの別のケースspukhafte Fernwirkungですか?

つまり、式を格納する変数/関数(ここでは整数のリスト(ListOfInts))を作成し、次に並列式ワーカーでその式にいくつかの関数を実行したいと思います交換ルールを受け取り、Minにしてください)。私は、これはいくつかのバグであると考えてい

(*some arbitrary rules that will convert some of the integers to negative values:*) 
rulez=Dispatch[Thread[Rule[Range[222],-Range[222]]]]; 

maxIndex = 333; 
Clear[ListOfInts] 
Scan[(ListOfInts[#]=RandomInteger[{1,999},55])&,Range[maxIndex ]] 
(*just for safety's sake:*) 
DistributeDefinitions[rulez, ListOfInts] 

Clear[IndexedFunk] 
(*I believe I have to have at least one value of IndexedFunk defined before I Share the definition to the workers:*) 
IndexedFunk[1]=Min[ListOfInts[1]]/.rulez 
(*... and this should let me retrieve the values back on the primary instance of MMA:*) 
SetSharedFunction[IndexedFunk] 

(*Now, here is the mysterious part: this just sits there on my multiprocessor machine for many minutes until suddenly a result appears. If I up maxIndex to say 99999 (and of course re-execute the above code again) then the effect can more clearly be seen.*) 
AbsoluteTiming[Short[ParallelMap[(IndexedFunk[#]=Min[ListOfInts[#]/.rulez])&, Range[maxIndex]]]] 

:私は、その関数の結果はまた、その結果、バックのMathematicaのメインインスタンス上で利用可能になり、他の変数/関数(IndexedFunk)の下で同じインデックスによってインデックスさせたいですしかし、私はまだMathematica Parallelを理解しようとしているので、この結論にはあまり自信がありません。 CPUがうんざりに遅くなっているにもかかわらず、実際にCPUを必要とせずに計算を実行できるという点で、それは驚異的です。

おそらく、マスタとスレーブのプロセス間で使用されている通信プロトコルが原因だと思っていたかもしれませんが、おそらく遅いので、実際に次のプロセスを送信するのを待っているときには、いくつかの定義やその他のビット。その場合、私はParallelMap[..., Method->"CoarsestGrained"]と思っていました。しかし、それはどちらもうまくいきません。

質問:「明らかに間違ったことをしていますか、これはバグですか?」

+0

DistributeDefinitions [...]、あなたは 'ListsOfInts'を意図しましたか?これは' ListOfInts'でしたか? –

答えて

3

恐れ入りますが、問題は、変数の共有定義にあります。 Mathematicaはカーネル間の変数のすべてのコピーに単一の一貫した値を保持しているため、その変数は大きな競合の単一点になります。カーネルは変数IndexedFunkを待っているキューに並んでいるため、CPUはアイドル状態であり、プロセス間通信またはマシン間通信にはほとんどの時間が費やされます。 Go figure。

ところで、私が知っているMathematicaのバージョンでは、関数SetSharedDefinitionはありません。あなたはおそらくSetSharedVariableと書こうとしていました。とにかくその邪悪な声を取り除く! 、競合を避けるためのペアのリストとして並列化計算から結果を返す、その後、メインのカーネルであなたの変数のdownvaluesにそれらを組み立てるには:

Clear[IndexedFunk] 
Scan[(IndexedFunk[#[[1]]] = #[[2]]) &, 
    ParallelMap[{#, Min[ListOfInts[#] /. rulez]} &, Range[maxIndex]] 
] 

ParallelMapが自動的に定義を配布するの面倒を見るので、DistributeDefinitionsへの呼び出し余分です。 (maxIndex変数を省略し、書かれたが、抜けが自動的にこの特定の場合においてParallelMapによって考慮されるマイナーな注意点として、それは正しくない。)

EDIT、NB !:自動配布にのみ適用されMathematicaのバージョン8へ。訂正のために@MikeHoneychurchに感謝します。

+0

コメント/質問として 'DistributeDefinitions'に関するあなたのコメントは余分なものはV8 +にのみ適用されると思いますか? –

+0

はい、私はV8が自動的に定義を配布すると思います。 – berniethejet

+0

@kkm、はい、あなたの解決策は私も到着したものです。私は、SharedFunctions(SetSharedDefinitionではなく)を使用することで、自動的に関数定義が自動的に処理されることを期待していました。しかし、私は定義の共有が競合を引き起こしていることをあなたがどのように知っているのか分かりません。新しいダウンバリューがIndexedFunkに追加されるたびに、これをすべてのカーネルに再送信する必要があると思いますか?これは理にかなっていますが、なぜこれがTaskManagerに表示されませんか? – berniethejet

関連する問題