私はPythonのmultiprocessing
モジュールの詳細を学び、プロセス間の通信のさまざまな手法を評価しようとしています。プロセス間でnumpy
アレイを転送するために、Pipe
,Queue
、およびArray
(すべてはmultiprocessing
)のパフォーマンスを比較するベンチマークを書きました。完全なベンチマークはhereです。ここでQueue
のためのテストの抜粋です:Pythonのマルチプロセスを使用した通信のためのOSXとLinuxのパフォーマンスの差
def process_with_queue(input_queue, output_queue):
source = input_queue.get()
dest = source**2
output_queue.put(dest)
def test_with_queue(size):
source = np.random.random(size)
input_queue = Queue()
output_queue = Queue()
p = Process(target=process_with_queue, args=(input_queue, output_queue))
start = timer()
p.start()
input_queue.put(source)
result = output_queue.get()
end = timer()
np.testing.assert_allclose(source**2, result)
return end - start
私は私のLinuxラップトップ上でこのテストを実行し、1000000の配列サイズのため、以下の結果を得た:
Using mp.Array: time for 20 iters: total=2.4869s, avg=0.12435s
Using mp.Queue: time for 20 iters: total=0.6583s, avg=0.032915s
Using mp.Pipe: time for 20 iters: total=0.63691s, avg=0.031845s
私が見て少し驚きましたArray
は共有メモリを使用しており、おそらく酸洗いを必要としないので、それほどうまく実行されませんが、私は制御できないnumpy
に何らかのコピーがあると仮定します。
しかし、私は次のような結果をMacBookの上(配列サイズ1000000のためもう一度)同じテストを実行し、そして得た:
Using mp.Array: time for 20 iters: total=1.6917s, avg=0.084587s
Using mp.Queue: time for 20 iters: total=2.3478s, avg=0.11739s
Using mp.Pipe: time for 20 iters: total=8.7709s, avg=0.43855s
実際のタイミングの違いであることは驚くべきことではない、もちろん異なるシステムが出来異なる性能を示す。 はなので、相対的タイミングの違いは驚くべきことです。
これを説明できるものは何ですか?これは私にとってかなり驚くべき結果です。 LinuxとWindows、あるいはOSXとWindowsの間にこのような違いがあるのは驚きではありませんが、私はこれらのことがOSXとLinuxの間で非常によく似ていると考えています。
This questionは、WindowsとOSXのパフォーマンスの違いに対処しています。我々は、Pythonでマルチプロセスについて話すとき
'Value'型と' Array'型はデータの安全性を保証するために 'Lock'に依存しています。ロックを取得することは、カーネルモードに切り替える必要があるため、かなり高価なアクションです。一方、シンプルなデータ構造をシリアライズすることは、現代のCPUが大部分の時間を費やしているため、そのコストはかなり低いです。 'Array'から' Lock'を削除するとパフォーマンスは向上しますが、データに対して競合条件を除外することはできません。 – noxdafox
@noxdafox完全なベンチマークコードを見ると、実際にベンチマークの 'Array'部分にロックを使用していないことがわかります。それでも、これはLinux上での 'Array'の相対的なパフォーマンスの貧弱さを説明しますが、必ずしもLinuxとOSXとの間の不一致を説明するものではありません。 – ddavella
あなたのMacBookはソリッドステートドライブを持ち、Linuxノートパソコンは回転ディスクを持っていますか? – Hannu