Python多处理/线程比虚拟机上的单个处理花费更长的时间

Khr*_*ris 5 python multithreading multiprocessing python-multithreading python-multiprocessing

我正在使用位于我公司大型机中的虚拟机.

我分配了4个核心,所以我正在尝试并行处理我的Python代码.我还不熟悉它,我遇到了意想不到的行为,即多处理/线程比单个处理需要更长的时间.我不知道我做错了什么,或者问题来自我的虚拟机.

这是一个例子:

import multiprocessing as mg
import threading
import math
import random
import time

NUM = 4

def benchmark():
  for i in range(1000000):
    math.exp(random.random())

threads = []
random.seed()

print "Linear Processing:"
time0 = time.time()
for i in range(NUM):
  benchmark()
print time.time()-time0

print "Threading:"
for P in range(NUM):
  threads.append(threading.Thread(target=benchmark))
time0 = time.time()
for t in threads:
  t.start()
for t in threads:
  t.join()
print time.time()-time0

threads = []
print "Multiprocessing:"
for i in range(NUM):
  threads.append(mg.Process(target=benchmark))
time0 = time.time()
for t in threads:
  t.start()
for t in threads:
  t.join()
print time.time()-time0
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

Linear Processing:
1.125
Threading:
4.56699991226
Multiprocessing:
3.79200005531
Run Code Online (Sandbox Code Playgroud)

线性处理在这里是最快的,这与我想要和期望的相反.我不确定如何执行join语句,所以我也用这样的连接做了一个例子:

for t in threads:
  t.start()
  t.join()
Run Code Online (Sandbox Code Playgroud)

现在这导致输出如下:

Linear Processing:
1.11500000954
Threading:
1.15300011635
Multiprocessing:
9.58800005913
Run Code Online (Sandbox Code Playgroud)

现在线程几乎和单个处理一样快,而多处理甚至更慢.

在任务管理器中观察处理器负载时,即使在进行多处理时,四个虚拟内核的单个负载也不会超过30%,因此我怀疑这里存在配置问题.

我想知道我是否正确地进行基准测试,如果这种行为真的像我想的那样奇怪.

Wil*_*ill 6

所以,首先,你没有做错任何事情,当我在我的Macbook Pro上运行你的例子时,使用cPython 2.7.12,我得到:

$ python test.py
Linear Processing:
0.733351945877
Threading:
1.20692706108
Multiprocessing:
0.256340026855
Run Code Online (Sandbox Code Playgroud)

但是,当我改变时,差异变得更加明显:

for i in range(1000000):
Run Code Online (Sandbox Code Playgroud)

至:

for i in range(100000000):
Run Code Online (Sandbox Code Playgroud)

差异更明显:

Linear Processing:
77.5861060619
Threading:
153.572453976
Multiprocessing:
33.5992660522
Run Code Online (Sandbox Code Playgroud)

现在为什么线程一直变慢?因为Global Interpreter Lock.threading模块唯一有用的就是等待I/O. 您的multiprocessing示例是执行此操作的正确方法.

所以,在你原来的例子中,哪个Linear Processing是最快的,我会把这归咎于启动进程的开销.当您进行少量工作时,通常可能需要花费更多时间来启动4个进程并等待它们完成,而不是仅仅在一个进程中同步完成工作.使用更大的工作量来更逼真地进行基准测试.