0

我正在尝试学习multiprocessingPython3.9 中的库。220500我比较的一件事是在由每个数据集的样本组成的数据集上重复计算的性能。我使用multiprocessing库然后使用for循环来做到这一点。

在我的测试中,我一直在使用 for 循环获得更好的性能。这是我正在运行的测试的代码。我正在计算具有 220500 个样本的信号的 FFT。我的实验涉及在每次测试中运行此过程一定次数。我正在通过将进程数分别设置为 10、100 和 1000 来测试这一点。

import time
import numpy as np 
from scipy.signal import get_window
from scipy.fftpack import fft
import multiprocessing
from itertools import product

def make_signal():
    # moved this code into a function to make threading portion of code clearer
    DUR = 5
    FREQ_HZ = 10
    Fs = 44100
    
    # precompute the size
    N = DUR * Fs

    # get a windowing function
    w = get_window('hanning', N)

    t = np.linspace(0, DUR, N)
    x = np.zeros_like(t)
    b = 2*np.pi*FREQ_HZ*t
    for i in range(50):
        x += np.sin(b*i)
    
    return x*w, Fs

def fft_(x, Fs):
    yfft = fft(x)[:x.size//2]
    xfft = np.linspace(0,Fs//2,yfft.size)
    return 2/yfft.size * np.abs(yfft), xfft


if __name__ == "__main__":
    # grab the raw sample data which will be computed by the fft function
    x = make_signal()
    # len(x) = 220500

    # create 5 different tests, each with the amount of processes below
    # array([    10,    100,   1000])
    tests_sweep = np.logspace(1,3,3, dtype=int)

    # sweep through the processes
    for iteration, test_num in enumerate(tests_sweep):
        # create a list of the amount of processes to give for each iteration
        fft_processes = []
        for i in range(test_num):
            fft_processes.append(x)

        start = time.time()
        
        # repeat the process for test_num amount of times (e.g. 10, 100, 1000)
        with multiprocessing.Pool() as pool:
            results = pool.starmap(fft_, fft_processes)
        end = time.time()
        print(f'{iteration}: Multiprocessing method with {test_num} processes took: {end - start:.2f} sec')

        start = time.time()
        for fft_processes in fft_processes:
            # repeat the process the same amount of time as the multiprocessing method using for loops
            fft_(*fft_processes)
        end = time.time()
        print(f'{iteration}: For-loop method with {test_num} processes took: {end - start:.2f} sec')
        print('----------')

这是我的测试结果。

0: Multiprocessing method with 10 processes took: 0.84 sec
0: For-loop method with 10 processes took: 0.05 sec
----------
1: Multiprocessing method with 100 processes took: 1.46 sec
1: For-loop method with 100 processes took: 0.45 sec
----------
2: Multiprocessing method with 1000 processes took: 6.70 sec
2: For-loop method with 1000 processes took: 4.21 sec
----------

为什么 for-loop 方法要快得多?我multiprocessing是否正确使用图书馆?谢谢。

4

1 回答 1

0

启动一个新进程需要大量开销。此外,必须将数据从一个进程复制到另一个进程(与正常的内存复制相比,同样需要一些开销)。

另一个方面是您应该将进程数限制为您拥有的核心数。重复也会使您产生流程转换成本。

这一点,再加上每个进程的计算量很少,这使得切换不值得。

我认为,如果您使信号显着延长(10 倍或 100 倍),您应该开始看到使用多核的一些好处。

还要检查您正在运行的操作是否已经在使用一些并行性。它们可能是用线程实现的,这些线程的成本要低得多(但从历史上看,在 python 中不能很好地工作,对 GIL 进行染色)。

于 2020-11-22T08:25:57.960 回答