如果进程数大于核心数量的一半,为什么性能会下降?

时间:2018-05-12 05:01:22

标签: linux python-3.x concurrency multiprocessing centos7

大家好我有以下Python程序,用于对多处理应用程序的性能进行基准测试。

#
# Date : 09/May/2018
# Platform : Linux
#

import os
import sys
import ctypes
import signal
import multiprocessing as mp

ncpu = 4
counter = 0
child_index = 0
process_list = []
shared_array = None

def HandleSignal(signum, frame) :

   total = 0
   print("Parent timeout hence terminate child")
   [hProc.terminate() for hProc in process_list]
   [hProc.join() for hProc in process_list]
   for each_count in shared_array :
      total += each_count
   print("{:,}".format(total))

def ChildHandleSignal(signum, frame) :

   # print("{} - {} : {:,}".format(child_index, os.getpid(), counter))
   shared_array[child_index] = counter
   sys.exit(0)

def entry_point(index, sarr) :

   global counter
   global child_index
   global shared_array

   child_index = index
   shared_array = sarr
   signal.signal(signal.SIGTERM, ChildHandleSignal)
   while True : counter += 1

   return

ncpu = int(sys.argv[1])
maxcpu = os.cpu_count()

if ncpu > maxcpu :

   print("Number of CPU greater than maximum CPU")
   print("Setting number of CPU to maximum")
   ncpu = maxcpu

shared_array = mp.Array(ctypes.c_int64, range(ncpu))
signal.signal(signal.SIGALRM, HandleSignal)
signal.alarm(5)

for I in range(ncpu) :

   p1 = mp.Process(target=entry_point, args=(I, shared_array, ))
   process_list.append(p1)
   p1.start()

   # I tried both with and with-out the below
   # statement. The outputs are much similar
   os.sched_setaffinity(p1.pid, {I})

我已在两台不同的机器上运行此程序

  1. 运行在8 VCPU Intel处理器上的Cent OS 7.x的Google云虚拟机
  2. 具有48核Intel处理器的Cent OS 7.X Linux机器
  3. 输出与使用的核心数量的关系图如下所示。从中我观察到输出增加,直到进程数达到核数/ 2并且在此之后下降。有人可以解释这种行为吗?

    enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

正如@IlyaBursov所说,这里的“问题”是超线程。

超线程不仅仅是魔术。超线程的真正目的是能够在等待其他进程的内存访问的延迟期间执行另一个进程或线程。

在您的情况下,您的代码太简单了,无法使用超线程获得性能。这只是一个在无限循环中递增的计数器。所有代码都可以放在L1缓存中,肯定没有缓存错过......

但是如果你添加太多的过程,两个过程之间的上下文切换成本是不可忽视的。