2017-06-28 11 views
1
当該

システム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は、システムメモリの半分だけで正常に動作しますか?それともメモリ帯域幅の問題ですか?これを理解しようとするために他に何ができますか?

答えて

0

ガベージコレクションを使用する言語では、これが問題です。最大RAMに近すぎると、GCを常に実行しようとするため、CPU使用率が増加します。

+0

私が言及したように、100GB以上のRAMがあります。 – tuttleorbuttle

0

問題を解決するのは、キャッシュメモリをクリアすることだけです。私は、OSがキャッシュ用に約200GBを使用していたときに、約256GBのメモリが必要なテストを実行しました。 OSがキャッシュを解放し始めたら、これは永遠に終わり、崩壊し始めました。このテストを実行した後に、free -mは3GBのキャッシュメモリしか示さなかった。私は同じベンチマークを実行し、それは以前見られたCPUの狂気のない予想された時間内に実行されました。パフォーマンスは繰り返し実行されても一定に保たれました。

OSのメモリキャッシュがアプリケーションのパフォーマンスに影響を与えないことを私がオンラインで読んでいるのとは対照的に、私の経験は、少なくともこの特定の使用例ではそうであると私に伝えています。

関連する問題