Ggg*_*ggg 44 python multiprocessing python-3.x
我有两段代码,我用它来学习Python 3.1中的多处理.我的目标是使用所有可用处理器的100%.但是,此处的代码片段仅在所有处理器上达到30% - 50%.
无论如何'强制'python使用全部100%?操作系统(Windows 7,64位)是否限制了Python对处理器的访问?虽然下面的代码片段正在运行,但我打开任务管理器并观察处理器的峰值,但从未达到并维持100%.除此之外,我还可以看到在此过程中创建和销毁了多个python.exe进程.这些过程如何与处理器相关?例如,如果我生成4个进程,则每个进程都不使用它自己的核心.相反,使用的流程是什么?他们共享所有核心吗?如果是这样,操作系统是否迫使进程共享内核?
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()
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
S.L*_*ott 41
要使用100%的所有核心,请不要创建和销毁新进程.
为每个核心创建一些进程并将它们与管道链接.
在操作系统级别,所有流水线进程同时运行.
您写的越少(您委托给操作系统的次数越多),您使用尽可能多的资源的可能性就越大.
python p1.py | python p2.py | python p3.py | python p4.py ...
Run Code Online (Sandbox Code Playgroud)
将最大限度地利用您的CPU.
Ioa*_*dis 13
您可以使用psutil将每个生成的进程固定multiprocessing到特定的CPU:
import multiprocessing as mp
import psutil
def spawn():
procs = list()
n_cpus = psutil.cpu_count()
for cpu in range(n_cpus):
affinity = [cpu]
d = dict(affinity=affinity)
p = mp.Process(target=run_child, kwargs=d)
p.start()
procs.append(p)
for p in procs:
p.join()
print('joined')
def run_child(affinity):
proc = psutil.Process() # get self pid
print('PID: {pid}'.format(pid=proc.pid))
aff = proc.cpu_affinity()
print('Affinity before: {aff}'.format(aff=aff))
proc.cpu_affinity(affinity)
aff = proc.cpu_affinity()
print('Affinity after: {aff}'.format(aff=aff))
if __name__ == '__main__':
spawn()
Run Code Online (Sandbox Code Playgroud)
注意:如评论所述,psutil.Process.cpu_affinitymacOS上不可用.
关于代码片段1:您的测试机器上有多少个核心/处理器?如果您只有2个CPU核心,那么运行其中50个进程对您没有任何帮助.实际上,您正在强制操作系统花费更多时间进行上下文切换,以便在CPU上下移动进程,而不是实际工作.
尝试将生成的进程数减少到核心数.所以"对于范围内的我(50):"应该变得像:
import os;
# assuming you're on windows:
for i in range(int(os.environ["NUMBER_OF_PROCESSORS"])):
...
Run Code Online (Sandbox Code Playgroud)
关于代码片段2:您正在使用multiprocessing.Lock,它一次只能由一个进程保存,因此您完全限制了此版本程序中的所有并行性.你已经序列化了一些东西,以便进程1到50开始,一个随机进程(比如进程7)获取锁.进程1-6和8-50都在线上:
l.acquire()
Run Code Online (Sandbox Code Playgroud)
当他们坐在那里他们只是在等待释放锁.根据Lock原语的实现,他们可能没有使用任何CPU,他们只是坐在那里使用系统资源,如RAM,但没有与CPU有用的工作.进程7计数并打印到1000然后释放锁.然后操作系统可以随机安排其余49个进程中的一个进行运行.无论哪一个先醒来,它都会获得锁定并继续运行,而其余48个等待锁定.这将继续整个计划.
基本上,代码片段2是使并发变得困难的一个例子.您必须通过许多进程或线程来管理对某些共享资源的访问.在这种特殊情况下,这些过程实际上没有理由需要相互等待.
因此,在这两者中,Snippet 1更接近于更有效地利用CPU.我认为适当调整进程数以匹配核心数将产生大大改善的结果.
纯Python中的最小示例:
def f(x):
while 1:
# ---bonus: gradually use up RAM---
x += 10000 # linear growth; use exponential for faster ending: x *= 1.01
y = list(range(int(x)))
# ---------------------------------
pass # infinite loop, use up CPU
if __name__ == '__main__': # name guard to avoid recursive fork on Windows
import multiprocessing as mp
n = mp.cpu_count() * 32 # multiply guard against counting only active cores
with mp.Pool(n) as p:
p.map(f, range(n))
Run Code Online (Sandbox Code Playgroud)
用法:在寒冷的天气进行预热(但可以随时将循环更改为没有意义的东西。)
警告:要退出,请不要拔插头或按住电源按钮,而请按Ctrl-C。
| 归档时间: |
|
| 查看次数: |
69647 次 |
| 最近记录: |