システム256 GBのRAMとのCentOSを実行する2-CPUのXeonプロセッササーバであります-2687W 0 @ 3.10GHzRAMの使用は、
各CPUには8つのコアがあるため、ハイパースレッディングの場合、システムには32プロセッサが/ proc/cpuinfoに表示されます。
このシステムを使用すると、いくつかのデータ処理でいくつかの特有のパフォーマンス上の問題が発生していることに気付きました。データ処理システムはPython 3.3.5(Anacondaを使用した環境設定)で構築されており、ファイルからデータを読み込み、数多くの配列を作成し、何らかの処理を行う一連のプロセスを生成します。
私は、生成されたさまざまなプロセス数で処理をテストしていました。一定数のプロセスまでは、パフォーマンスは比較的一定のままでした。しかし、一度16プロセスに達したら、numpy.abs()コールは、それ以外の場合に比べて約10秒長く、約2秒から20秒以上かかることに気づきました。
このテストでのメモリ使用量の合計は問題にはなりませんでした。 256 GBのシステムRAMのうち、htopは100 GB以上の空き容量を示し、meminfoはスワップしていませんでした。
私は16プロセスを使用した別のテストを実行しましたが、合計メモリ使用量が75GB前後のデータを少なくロードしました。この場合、numpy.abs()コールは1秒かかる(データの半分であるため)。システム・ラムの半分以下を使用している24個のプロセスに行くと、numpy.abs()コールも同様に約1秒かかりました。だから私はもはや10倍のパフォーマンスを見ていませんでした。
ここで興味深いのは、システムメモリの半分以上が使用されているように見えますが、パフォーマンスはひどく低下します。これはそうではないようですが、他の説明はありません。
私は、処理フレームワークが何をするのかをシミュレートするPythonスクリプトを書いています。私はsproiningプロセス、マルチプロセッシング、スプール、apply_async()、concurrent.futures、およびmultiprocessing Processのさまざまな方法を試みましたが、それらはすべて同じ結果をもたらします。
import pdb
import os
import sys
import time
import argparse
import numpy
import multiprocessing as mp
def worker(n):
print("Running worker", n)
NX = 20000
NY = 10000
time_start = time.time()
x1r = numpy.random.rand(NX,NY)
x1i = numpy.random.rand(NX,NY)
x1 = x1r + 1j * x1i
x1a = numpy.abs(x1)
print(time.time() - time_start)
def proc_file(nproc):
procs = {}
for i in range(0,nproc):
procs[i] = mp.Process(target = worker, args = (i,))
procs[i].start()
for i in range(0,nproc):
procs[i].join()
if __name__ == "__main__":
time_start = time.time()
DEFAULT_NUM_PROCS = 8
ap = argparse.ArgumentParser()
ap.add_argument('-nproc', default = DEFAULT_NUM_PROCS, type = int,
help = "Number of cores to run in parallel, default = %d" \
% DEFAULT_NUM_PROCS)
opts = ap.parse_args()
nproc = opts.nproc
# spawn processes
proc_file(nproc)
time_end = time.time()
print('Done in', time_end - time_start, 's')
プロセスの様々な数のため、一部の結果は:
$ python test_multiproc_2.py -nproc 4
Running worker 0
Running worker 1
Running worker 2
Running worker 3
12.1790452003479
12.180120944976807
12.191224336624146
12.205029010772705
Done in 12.22369933128357 s
$ python test_multiproc_2.py -nproc 8
Running worker 0
Running worker 1
Running worker 2
Running worker 3
Running worker 4
Running worker 5
Running worker 6
Running worker 7
12.685678720474243
12.692482948303223
12.704699039459229
13.247581243515015
13.253047227859497
13.261905670166016
13.29712200164795
13.458561897277832
Done in 13.478906154632568 s
$ python test_multiproc_2.py -nproc 16
Running worker 0
Running worker 1
Running worker 2
Running worker 3
Running worker 4
Running worker 5
Running worker 6
Running worker 7
Running worker 8
Running worker 9
Running worker 10
Running worker 11
Running worker 12
Running worker 13
Running worker 14
Running worker 15
135.4193136692047
145.7047221660614
145.99714827537537
146.088121175766
146.3116044998169
146.94093680381775
147.05147790908813
147.4889578819275
147.8443088531494
147.92090320587158
148.32112169265747
148.35854578018188
149.11916518211365
149.22325253486633
149.45888781547546
149.74489760398865
Done in 149.97473335266113 s
ので、4と8のプロセスはほぼ同じですが、16個のプロセスとそれが10倍遅いです!目立つのは16プロセスの場合で、メモリ使用量は146 GBです。
私は半分にnumpyの配列のサイズを小さくして、もう一度それを実行した場合:だから
$ python test_multiproc_2.py -nproc 4
Running worker 1
Running worker 0
Running worker 2
Running worker 3
5.926755666732788
5.93787956237793
5.949704885482788
5.955750226974487
Done in 5.970340967178345 s
$ python test_multiproc_2.py -nproc 16
Running worker 1
Running worker 3
Running worker 0
Running worker 2
Running worker 5
Running worker 4
Running worker 7
Running worker 8
Running worker 6
Running worker 11
Running worker 9
Running worker 10
Running worker 13
Running worker 12
Running worker 14
Running worker 15
7.728739023208618
7.751606225967407
7.754587173461914
7.760802984237671
7.780809164047241
7.802706241607666
7.852390766143799
7.8615334033966064
7.876686096191406
7.891174793243408
7.916942834854126
7.9261558055877686
7.947092771530151
7.967057704925537
8.012752294540405
8.119316577911377
Done in 8.135530233383179 s
、16と4つのプロセス間のパフォーマンスヒットの少しが、見られているものに近い何もより大きいアレイで。私は、配列のサイズを2倍して、もう一度それを実行した場合
また、:
$ python test_multiproc_2.py -nproc 4
Running worker 1
Running worker 0
Running worker 2
Running worker 3
23.567795515060425
23.747386693954468
23.76904606819153
23.781703233718872
Done in 23.83848261833191 s
$ python test_multiproc_2.py -nproc 8
Running worker 1
Running worker 0
Running worker 3
Running worker 2
Running worker 5
Running worker 4
Running worker 6
Running worker 7
103.20905923843384
103.52968168258667
103.62282609939575
103.62272334098816
103.77079129219055
103.77456998825073
103.86126565933228
103.87058663368225
Done in 104.26257705688477 s
8でのプロセスを今、RAMの使用は145ギガバイトがヒットし、5倍のパフォーマンスヒットがあります。
私はこれをどうするか分かりません。システムメモリの半分以上が使用されている場合、システムは基本的に使用不可能になります。しかし、私はそれがちょうど偶然であり、何かが原因であるかどうかはわかりません。
これはPythonのものですか?またはシステムアーキテクチャのこと?各物理CPUは、システムメモリの半分だけで正常に動作しますか?それともメモリ帯域幅の問題ですか?これを理解しようとするために他に何ができますか?
私が言及したように、100GB以上のRAMがあります。 – tuttleorbuttle