为什么实施多处理会使我的程序变慢

Why does implementing multiprocessing makes my program slower

我正在尝试在我的代码中实现多处理以使其更快。

为了更容易理解,我只想说该程序使用曲线库的线性组合拟合观察到的曲线,并从中测量观察到的曲线的属性。

我必须对 400 多条曲线执行此操作,并且为了估计这些属性的误差,我执行了 Monte Carlo 模拟,这意味着每次计算我都必须迭代多次。

这需要大量的时间和工作,当然我相信这是一个 CPU 的任务,我想我会在错误估计步骤中使用多处理。这是我的代码的简化:

没有多处理

import numpy as np
import fitting_package
import multiprocessing


def estimate_errors(best_fit_curve, signal_to_noise, fit_kwargs, iterations=100)
    results = defaultdict(list)
    def fit(best_fit_curve, signal_to_noise, fit_kwargs, results):
        # Here noise is added to simulate a new curve (Monte Carlo simulation)
        noise = best_fit/signal_to_noise
        simulated_curve = np.random.normal(best_fit_curve, noise)
        # The arguments from the original fit (outside the error estimation) are passed to the fitting
        fit_kwargs.update({'curve' : simulated_curve})
        # The fit is performed and it returns the properties packed together
        solutions = fitting_package(**fit_kwargs)
        # There are more properties so this is a simplification
        property_1, property_2 = solutions
        aux_dict = {'property_1' : property_1, 'property_2' : property_2}
        for key, value in aux_dict.items():
            results[key].append(values)
    for _ in range(iterations):
        fit(best_fit_curve, signal_to_noise, fit_kwargs, results)
    return results

多处理

def estimate_errors(best_fit_curve, signal_to_noise, fit_kwargs, iterations=100)
    def fit(best_fit_curve, signal_to_noise, fit_kwargs, queue):
        results = queue.get()
        noise = best_fit/signal_to_noise
        simulated_curve = np.random.normal(best_fit_curve, noise)
        fit_kwargs.update({'curve' : simulated_curve})
        solutions = fitting_package(**fit_kwargs)
        property_1, property_2 = solutions
        aux_dict = {'property_1' : property_1, 'property_2' : property_2}
        for key, value in aux_dict.items():
            results[key].append(values)
        queue.put(results)
    process_list = []
    queue = multiprocessing.Queue()
    queue.put(defaultdict(list))
    for _ in range(iterations):
        process = multiprocessing.Process(target=fit, args=(best_fit_curve, signal_to_noise, fit_kwargs, queue))
        process.start()
        process_list.append(process)
    for p in process_list:
        p.join()
    results = queue.get()
    return results

我原以为使用多处理会节省时间,但实际上它比其他方法花费的时间多一倍多。为什么是这样?无论如何,我可以通过多处理让它更快吗?

I thought using multiprocessing would save time, but it actually takes more than double than the other way to do it. Why is this?

启动一个进程需要很长时间(至少在计算机方面是这样)。它还使用大量内存。

在您的代码中,您在 100 个单独的 OS 进程中启动了 100 个单独的 Python 解释器。这需要很长时间,所以除非每个进程 运行 的时间都非常长,否则启动进程所花费的时间将支配它实际执行有用工作的时间。

除此之外,除非您实际上有 100 个未使用的 CPU 核心,否则这 100 个进程将花费大部分时间等待彼此完成。更糟糕的是,由于它们都具有相同的优先级,OS 会尝试给它们每个人相当多的时间,所以它会 运行 它们一段时间,然后暂停它们,运行 给其他人一点时间,暂停他们,等等。所有这些安排 需要时间。

并行工作负载多于并行资源不能加速您的程序,因为无论如何它们都必须等待一个接一个地执行。

如果并行任务的时间不受创建、管理、调度和重新加入并行任务的时间支配,则并行只会加快您的程序。