在2CPU Xeon服务器上使用RAM导致python3性能不佳

2024-04-25 05:50:20 发布

您现在位置:Python中文网/ 问答频道 /正文

该系统是一个2 CPU Xeon服务器,运行CentOS,256 GB RAM:

2个Intel(R)Xeon(R)CPU E5-2687W 0@3.10GHz

每个CPU有8个内核,因此通过超线程,系统有32个处理器显示在/proc/cpuinfo中。你知道吗

在使用这个系统时,我注意到一些数据处理中的特殊性能问题。数据处理系统是在python3.3.5(Anaconda环境设置)中构建的,它产生了一系列进程,这些进程从文件中读取数据,创建一些numpy数组,并进行一些处理。你知道吗

我正在用生成的不同数量的进程测试处理过程。在一定数量的进程中,性能保持相对稳定。然而,当我得到16个进程时,我注意到numpy.abs公司()开始通话的时间大约是正常通话时间的10倍,从2秒到20秒或更长。你知道吗

现在,这个测试中的总内存使用量不是问题。在256gb的系统内存中,htop显示有100+GB的空闲空间,meminfo没有显示任何交换。你知道吗

我运行了另一个测试,使用16个进程,但加载的数据较少,总内存使用量约为75GB。在这种情况下numpy.abs公司()呼叫需要1秒(这是预期的,因为它是数据的一半)。到了24个进程,仍然使用不到一半的系统ramnumpy.abs公司()呼叫同样花费了大约1秒。所以我再也看不到10倍的表现了。你知道吗

有趣的是,如果使用了超过一半的系统内存,性能会严重下降。似乎不应该是这样,但我没有其他解释。你知道吗

我编写了一个Python脚本,模拟了处理框架的功能。我试过各种各样的方法,多处理池应用\u async(),期货,以及多处理过程,它们都给出相同的结果。你知道吗

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进程的情况下,内存使用率达到146gb。你知道吗

如果我将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个进程之间的性能会有一点下降,但与更大阵列的性能相差甚远。你知道吗

另外,如果我将数组大小加倍并再次运行它:

$ 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使用达到145GB,性能提高了5倍。你知道吗

我不知道该怎么办。如果使用了超过一半的系统内存,则系统基本上不可用。但是,我不知道这是否只是巧合,还有别的原因。你知道吗

这是Python的东西吗?还是系统架构?是否每个物理CPU只能在一半系统内存的情况下运行良好?还是内存带宽问题?我还能做些什么来解决这个问题?你知道吗


Tags: 内存inpytestimportnumpytime进程
1条回答
网友
1楼 · 发布于 2024-04-25 05:50:20

这是使用垃圾收集的语言的一个问题:如果您太接近最大RAM,它们就会开始一直尝试运行GC,从而导致CPU使用率的增加。你知道吗

相关问题 更多 >