Python数字.fft在子进程中运行时非常慢(慢10倍)

2024-07-07 08:22:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我找到了numpy.fft.fft(及其变体)在后台运行时非常慢。这是我所说的一个例子

import numpy as np
import multiprocessing as mproc
import time
import sys

# the producer function, which will run in the background and produce data
def Producer(dataQ):
    numFrames = 5
    n = 0
    while n < numFrames:
        data = np.random.rand(3000, 200)
        dataQ.put(data)   # send the datta to the consumer
        time.sleep(0.1)  # sleep for 0.5 second, so we dont' overload CPU
        n += 1            

# the consumer function, which will run in the backgrounnd and consume data from the producer
def Consumer(dataQ):
    while True:
        data = dataQ.get()
        t1 = time.time()
        fftdata = np.fft.rfft(data, n=3000*5)
        tDiff = time.time() - t1
        print("Elapsed time is %0.3f" % tDiff)
        time.sleep(0.01)
        sys.stdout.flush()

# the main program  if __name__ == '__main__': is necessary to prevent this code from being run
# only when this program is started by user
if __name__ == '__main__':     
    data = np.random.rand(3000, 200)
    t1 = time.time()
    fftdata = np.fft.rfft(data, n=3000*5, axis=0)
    tDiff = time.time() - t1
    print("Elapsed time is %0.3f" % tDiff)

    # generate a queue for transferring data between the producedr and the consumer
    dataQ = mproc.Queue(4)

    # start up the processoso
    producerProcess = mproc.Process(target=Producer, args=[dataQ], daemon=False)
    consumerProcess = mproc.Process(target=Consumer, args=[dataQ], daemon=False)
    print("starting up processes")

    producerProcess.start()
    consumerProcess.start()
    time.sleep(10) # let program run for 5 seconds

    producerProcess.terminate()
    consumerProcess.terminate()

它在我的机器上产生的输出:

^{pr2}$

正如你所看到的,它在后台运行时大约慢了10倍,我不明白为什么会这样。这个时间。睡觉()调用应该确保另一个进程(主进程和生产者进程)在计算FFT时不做任何事情,因此它应该使用所有的核心。我通过Windows任务管理器检查了CPU的利用率,当numpy.fft.fft在单进程和多进程情况下都大量调用。在

有人知道怎么回事吗?在


Tags: therunimportfftnumpydatatime进程
1条回答
网友
1楼 · 发布于 2024-07-07 08:22:08

主要问题是后台线程中的fft调用是:

fftdata = np.fft.rfft(data, n=3000*5)

而不是:

^{pr2}$

对我来说一切都不同了。在

还有一些事情值得注意。与其让time.sleep()到处都是,为什么不让处理器自己来处理呢?此外,您可以使用

consumerProcess.join()

然后让producer进程在完成数据加载后运行dataQ.put(None),并在使用者进程中中断循环,即:

def Consumer(dataQ):
    while True:
        data = dataQ.get()
        if(data is None):
            break
        ...

相关问题 更多 >