KPM*_*KPM 10 python windows performance multiprocessing parallelism-amdahl
我试图在Python(Windows Server 2012)中实现多处理,并且无法实现我期望的性能提升程度.特别是,对于几乎完全独立的一组任务,我希望通过额外的内核进行线性改进.
我理解 - 尤其是在Windows上 - 开启新流程涉及开销[1],底层代码的许多怪癖可能会妨碍干净的趋势.但理论上,对于完全并行化的任务,趋势最终仍应接近线性[2] ; 如果我正在处理部分连续任务[3],或者可能是后勤.
但是,当我在主要检查测试函数(下面的代码)上运行multiprocessing.Pool N_cores=36时,在我进入预期性能之前,我得到了一个近乎完美的平方根关系(我服务器上的物理核心数)额外的逻辑核心.
这是我的性能测试结果图:

(" 归一化性能 "是[具有1个 CPU核心的运行时间]除以[具有N个 CPU核心的运行时间]).
通过多重处理使收益大幅减少是否正常?或者我错过了实施的内容?
import numpy as np
from multiprocessing import Pool, cpu_count, Manager
import math as m
from functools import partial
from time import time
def check_prime(num):
    #Assert positive integer value
    if num!=m.floor(num) or num<1:
        print("Input must be a positive integer")
        return None
    #Check divisibility for all possible factors
    prime = True
    for i in range(2,num):
        if num%i==0: prime=False
    return prime
def cp_worker(num, L):
    prime = check_prime(num)
    L.append((num, prime))
def mp_primes(omag, mp=cpu_count()):
    with Manager() as manager:
        np.random.seed(0)
        numlist = np.random.randint(10**omag, 10**(omag+1), 100)
        L = manager.list()
        cp_worker_ptl = partial(cp_worker, L=L)
        try:
            pool = Pool(processes=mp)   
            list(pool.imap(cp_worker_ptl, numlist))
        except Exception as e:
            print(e)
        finally:
            pool.close() # no more tasks
            pool.join()
        return L
if __name__ == '__main__':
    rt = []
    for i in range(cpu_count()):
        t0 = time()
        mp_result = mp_primes(6, mp=i+1)
        t1 = time()
        rt.append(t1-t0)
        print("Using %i core(s), run time is %.2fs" % (i+1, rt[-1]))
注意:我知道对于这个任务来说,实现多线程可能更有效,但是由于GIL,这个简化模拟的实际脚本与Python多线程不兼容.
@KellanM值得 进行定量性能监测[+1]
我错过了实施的内容吗?
虽然你已经表达了对" 额外核心的线性改进 "的期望,但由于几个原因(甚至共产主义的炒作未能免费提供任何东西),这在实践中几乎不会出现.
Gene AMDAHL制定了收益递减的初始法则.

一个更新的,重新制定的版本,还考虑了流程管理{setup | terminate}的影响 - 附加开销成本,并试图处理原子性处理(给定大型工作包有效载荷不能轻易地重新位于/重新分布在大多数常见编程系统中的可用CPU核心池上(除了一些确实具体的微调度技术,如语义设计的PARLANSE或LLNL的SISAL中所展示的那些在过去已经如此丰富多彩).
如果确实对这个领域感兴趣,可以总是通过实验来衡量和比较流程管理的实际成本(加上数据流成本,加上内存分配成本,......直到流程终止和结果重新组装为主过程)以便定量公平地记录和评估使用更多CPU核心的附加成本/效益比(这将获得python,重新实现整个python-interpreter状态,包括其所有的内存状态,之前第一个有用的操作将在第一个生成和设置过程中执行.
表现不佳(低于前一种情况)
,如果不是灾难性的影响(从下面的后一种情况下),
任生病工程资源映射的政策,是它
的" 下预约 "从池中-resources CPU -cores 
或
一个此处还讨论了 " 过度预订 " - 来自RAM空间池的资源
上面重新制定的阿姆达尔定律的链接将帮助您评估收益递减点,而不是支付超过收到的金额.
Hoefinger et Haunschmid实验可以作为一个很好的实际证据,越来越多的处理节点(无论是本地O/S管理的CPU核心,还是NUMA分布式架构节点)将如何开始降低最终性能,
其中一个点收益递减(在开销不可知的阿姆达尔定律中证明)
实际上将开始成为一个点,之后你支付的金额超过收到.:
NUMA /非地方性问题得到了他们的意见,进入了关于HPC级调整(缓存/内存计算策略)的扩展的讨论,并且可能 - 作为副作用 - 帮助检测缺陷(如@所报告的)eryksun上面).有人可以通过使用lstopo工具来查看一个人的平台实际NUMA拓扑,看一下操作系统正在尝试使用的抽象,一旦调度"正常" - [CONCURRENT]在这样的NUMA资源拓扑上执行任务:
| 归档时间: | 
 | 
| 查看次数: | 679 次 | 
| 最近记录: |