在多处理模块中使用100%的核心

时间:2011-04-25 23:30:01

标签: python python-3.x multiprocessing

我有两段代码,我用它来学习Python 3.1中的多处理。我的目标是使用所有可用处理器的100%。 但是,此处的代码片段仅在所有处理器上达到30% - 50%。

无论如何'强制'python使用全部100%? 操作系统(Windows 7,64位)是否限制了Python对处理器的访问? 虽然下面的代码片段正在运行,但我打开任务管理器并观察处理器的峰值,但从未达到并维持100%。 除此之外,我还可以看到在此过程中创建和销毁了多个python.exe进程。这些过程如何与处理器相关?例如,如果我生成4个进程,则每个进程都不使用它自己的核心。相反,使用的流程是什么?他们共享所有核心吗?如果是这样,操作系统是否强制进程共享内核?

代码段1

import multiprocessing

def worker():
    #worker function
    print ('Worker')
    x = 0
    while x < 1000:
        print(x)
        x += 1
    return

if __name__ == '__main__':
    jobs = []
    for i in range(50):
        p = multiprocessing.Process(target=worker)
        jobs.append(p)
        p.start()

代码段2

from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    print('worker ', i)
    x = 0
    while x < 1000:
        print(x)
        x += 1
    l.release()

if __name__ == '__main__': 
    lock = Lock()
    for num in range(50):
        Process(target=f, args=(lock, num)).start()

6 个答案:

答案 0 :(得分:37)

要使用100%的核心,请不要创建和销毁新进程。

为每个核心创建一些进程并将它们与管道链接。

在操作系统级别,所有流水线进程同时运行。

您写的越少(您委托给操作系统的次数越多)您越有可能使用尽可能多的资源。

python p1.py | python p2.py | python p3.py | python p4.py ...

最大限度地利用你的CPU。

答案 1 :(得分:13)

You can use psutil to pin each process spawned by multiprocessing to a specific CPU:

:firsttime
cls
echo Welcome! Bla bla bla
*making reg.txt so when you start app next time
it wont open firsttime anymore*

Note: As commented, psutil.Process.cpu_affinity is not available on macOS.

答案 2 :(得分:6)

关于代码段1:您的测试计算机上有多少个核心/处理器?如果您只有2个CPU核心,那么运行其中50个进程对您没有任何帮助。实际上,您正在强制操作系统花费更多时间进行上下文切换,以便在CPU上下移动进程,而不是实际工作。

尝试将生成的进程数减少到核心数。所以“对于我在范围内(50):”应该变成类似的东西:

import os;
# assuming you're on windows:
for i in range(int(os.environ["NUMBER_OF_PROCESSORS"])):
    ...

关于代码片段2:您正在使用multiprocessing.Lock,它一次只能由一个进程保存,因此您完全限制了此版本程序中的所有并行性。你已经序列化了一些东西,以便进程1到50开始,一个随机进程(比如进程7)获取锁。进程1-6和8-50都在线上:

l.acquire()

当他们坐在那里时他们只是在等待释放锁。根据Lock原语的实现,他们可能没有使用任何CPU,他们只是坐在那里使用系统资源,如RAM,但没有与CPU有用的工作。进程7计数并打印到1000然后释放锁。然后操作系统可以随机安排其余49个进程中的一个进行运行。无论哪一个先醒来,它都会获得锁定并继续运行,而其余48个等待锁定。这将继续整个计划。

基本上,代码片段2是使并发变得困难的一个例子。您必须通过许多进程或线程来管理对某些共享资源的访问。在这种特殊情况下,这些过程实际上没有理由需要相互等待。

因此,在这两者中,Snippet 1更接近于更有效地利用CPU。我认为适当调整进程数以匹配核心数将产生大大改善的结果。

答案 3 :(得分:5)

纯Python中的最小示例:

def f(x):
    while 1:
        pass  # infinite loop

import multiprocessing as mp
n_cores = mp.cpu_count()
with mp.Pool(n_cores) as p:
    p.map(f, range(n_cores))

用法:在寒冷的天气进行预热(但可以随时将循环更改为没有意义的东西)

警告:退出时,请勿拔下插头或按住电源按钮,而应按Ctrl-C。

答案 4 :(得分:0)

我建议使用 Joblib 库,它是用于多处理的好库,可用于许多ML应用程序,sklearn等中。

cgetAction

from joblib import Parallel, delayed Parallel(n_jobs=-1, prefer="processes", verbose=6)( delayed(function_name)(parameter1, parameter2, ...) for parameter1, parameter2, ... in object ) 是并发作业的数量。如果要在运行代码的计算机上使用所有可用的内核,请设置n_jobs

此处有关参数的更多详细信息:https://joblib.readthedocs.io/en/latest/generated/joblib.Parallel.html

在您的情况下,可能的实现方式是:

n=-1

答案 5 :(得分:-11)

回答你的问题:

  

无论如何'强制'python使用全部100%?

不是我听说过

  

操作系统(Windows 7,64位)是否限制了Python对处理器的访问?

是和否,是的:如果python占用100%,Windows将冻结。不,您可以授予python Admin Priviledges,这将导致锁定。

  

这些流程如何与处理器相关?

从操作系统级别来看,它们并不是那些python“进程”是由OS Handler在需要处理时处理的线程。

  

相反,使用的流程是什么?他们共享所有核心吗?如果是这样,操作系统是否强制进程共享内核?

他们正在共享所有核心,除非您启动一个具有设置为某个核心(在多核系统中)的亲缘关系的python实例,您的流程将被拆分为哪个永远无核心的处理。所以是的,操作系统默认强制核心共享(或者技术上是python)

如果您对python核心亲和力感兴趣,请查看affinity package for python