在我使用的linux系统上,调度程序不是很慷慨,给从python的多处理模块产生的子进程提供了cpu时间。在4核机器上使用4个子程序时,根据ps
,我获得了大约22%的CPU。但是,如果子进程是shell的子进程,而不是python程序,则它会达到接近100%的CPU。但是多处理是一个比手动分割我的数据更好的接口,并为每个分割运行单独的python程序,并且最好的两个世界(代码组织和高CPU利用率)。我尝试设置流程'对-20的好感,但这没有帮助。
我想知道用一些选项重新编译linux内核是否有助于调度程序为python多处理工作者提供更多的CPU时间。也许有相关的配置选项?
我使用的确切版本是:
$ uname -a
Linux <hostname> 3.19.0-39-generic #44~14.04.1-Ubuntu SMP Wed Dec 2 10:00:35 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
如果这可能与我使用多处理的方式有关,则其格式如下:
with Pool(4) as p:
p.map(function,data)
更新:
这不是一个可重现的问题。这里报告的结果来自几天前,我再次运行测试,多处理过程和我希望的一样快。也许这个问题应该被删除,误导人们对multiprocessing
期望的表现不会有好处。
答案 0 :(得分:2)
我不相信你的基准测试是作为独立任务执行的,正如你可能认为的那样。你没有显示function
的代码,但我怀疑它有一些同步。
我写了以下基准。如果我使用--fork
或--mp
选项运行脚本,我总是获得400%的CPU利用率(在我的四核机器上),并且可比的总执行时间大约为18秒。但是,如果使用--threads
选项调用,则程序有效地按顺序运行,只需要大约100%的CPU利用率,并且需要一分钟才能完成mentioned dave的原因。
import multiprocessing
import os
import random
import sys
import threading
def find_lucky_number(x):
prng = random.Random()
prng.seed(x)
for i in range(100000000):
prng.random()
return prng.randint(0, 100)
def with_threading(inputs):
callback = lambda x : print(find_lucky_number(x))
threads = [threading.Thread(target=callback, args=(x,)) for x in inputs]
for t in threads:
t.start()
for t in threads:
t.join()
def with_multiprocessing(inputs):
with multiprocessing.Pool(len(inputs)) as pool:
for y in pool.map(find_lucky_number, inputs):
print(y)
def with_forking(inputs):
pids = list()
for x in inputs:
pid = os.fork()
if pid == 0:
print(find_lucky_number(x))
sys.exit(0)
else:
pids.append(pid)
for pid in pids:
os.waitpid(pid, 0)
if __name__ == '__main__':
inputs = [1, 2, 3, 4]
if sys.argv[1] == '--threads':
with_threading(inputs)
if sys.argv[1] == '--mp':
with_multiprocessing(inputs)
elif sys.argv[1] == '--fork':
with_forking(inputs)
else:
print("What should I do?", file=sys.stderr)
sys.exit(1)
答案 1 :(得分:1)
欢迎使用CPython Global Interpreter Lock。你的线程显示为与linux内核不同的进程(这就是通常在Linux中实现线程的方式:每个线程都有自己的进程,所以内核可以安排它们)。
那么为什么Linux的调度不止一次运行(这就是为什么你的4核机器平均减去25%减去一点开销)? python解释器在解释每个线程时持有一个锁,从而阻止其他线程运行(因此无法安排它们)。
要解决这个问题,你可以: