Python numpy.fft在子流程中运行时非常慢(慢10倍)
我发现numpy.fft.fft(及其变体)在后台运行时非常慢。这是我所说的一个例子Python numpy.fft在子流程中运行时非常慢(慢10倍),python,numpy,multiprocessing,fft,Python,Numpy,Multiprocessing,Fft,我发现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 whil
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()
如您所见,在后台运行时,速度大约慢10倍,我不明白为什么会出现这种情况。调用time.sleep()应该确保在计算FFT时,另一个进程(主进程和生产者进程)没有做任何事情,因此它应该使用所有内核。我通过Windows任务管理器检查了CPU利用率,在单进程和多进程情况下大量调用numpy.fft.fft时,CPU利用率似乎高达25%
有人知道发生了什么吗?主要问题是后台线程中的fft调用是:
fftdata = np.fft.rfft(data, n=3000*5)
而不是:
fftdata = np.fft.rfft(data, n=3000*5, axis=0)
这对我来说完全不同
还有一些事情值得注意。与其到处都有time.sleep()
,为什么不让处理器自己处理呢?此外,您可以使用
consumerProcess.join()
然后让生产者进程在完成数据加载后运行dataQ.put(None)
,并在消费者进程中中断循环,即:
def Consumer(dataQ):
while True:
data = dataQ.get()
if(data is None):
break
...
主要问题是后台线程中的fft调用是:
fftdata = np.fft.rfft(data, n=3000*5)
而不是:
fftdata = np.fft.rfft(data, n=3000*5, axis=0)
这对我来说完全不同
还有一些事情值得注意。与其到处都有time.sleep()
,为什么不让处理器自己处理呢?此外,您可以使用
consumerProcess.join()
然后让生产者进程在完成数据加载后运行dataQ.put(None)
,并在消费者进程中中断循环,即:
def Consumer(dataQ):
while True:
data = dataQ.get()
if(data is None):
break
...
主要问题是后台线程中的fft调用是:
fftdata = np.fft.rfft(data, n=3000*5)
而不是:
fftdata = np.fft.rfft(data, n=3000*5, axis=0)
这对我来说完全不同
还有一些事情值得注意。与其到处都有time.sleep()
,为什么不让处理器自己处理呢?此外,您可以使用
consumerProcess.join()
然后让生产者进程在完成数据加载后运行dataQ.put(None)
,并在消费者进程中中断循环,即:
def Consumer(dataQ):
while True:
data = dataQ.get()
if(data is None):
break
...
主要问题是后台线程中的fft调用是:
fftdata = np.fft.rfft(data, n=3000*5)
而不是:
fftdata = np.fft.rfft(data, n=3000*5, axis=0)
这对我来说完全不同
还有一些事情值得注意。与其到处都有time.sleep()
,为什么不让处理器自己处理呢?此外,您可以使用
consumerProcess.join()
然后让生产者进程在完成数据加载后运行dataQ.put(None)
,并在消费者进程中中断循环,即:
def Consumer(dataQ):
while True:
data = dataQ.get()
if(data is None):
break
...
是的,我意识到这一次我有一个帖子。fft默认沿最后一个轴进行,因此我不以相同的方式进行fft。真正的问题是,对于某些输入大小,numpy.fft非常慢。但在我的例子中,我可以将pad归零到接近2的幂次方(比如nfftpts=int(2**np.round(np.log2(nfftpts)),来解决这个问题,比如time.sleep(),我发现如果没有它,CPU使用率会跳得很高。这只是一个测试程序,但在实际的、复杂得多的程序中,进程总是在运行,直到收到关机消息。但它们并不总是收集数据。实际的程序基本上用于异步数据收集、处理和显示,以提高速度因为Python线程不是并发的,所以要获得速度优势,唯一对我有意义的方法就是多个进程。是的,我意识到这是一个很短的时间,我有一个post.numpy.fft沿最后一个轴的默认值,所以我没有以同样的方式进行fft。真正的问题是,对于某些输入大小,numpy.fft非常有用慢。但是在我的例子中,我可以将pad归零到接近2的幂(比如nfftpts=int(2**np.round(np.log2(nfftpts))),来解决这个问题,比如time.sleep(),我发现如果没有它,CPU使用率会跳得很高。这只是一个测试程序,但在实际的、复杂得多的程序中,进程总是在运行,直到收到关机消息。但它们并不总是收集数据。实际的程序基本上用于异步数据收集、处理和显示,以提高速度因为Python线程不是并发的,所以要获得速度优势,唯一对我有意义的方法就是多个进程。是的,我意识到这是一个很短的时间,我有一个post.numpy.fft沿最后一个轴的默认值,所以我没有以同样的方式进行fft。真正的问题是,对于某些输入大小,numpy.fft非常有用慢。但是在我的例子中,我可以将pad归零到接近2的幂(比如nfftpts=int(2**np.round(np.log2(nfftpts))),来解决这个问题,比如time.sleep(),我发现如果没有它,CPU使用率会跳得很高。这只是一个测试程序,但在实际的、复杂得多的程序中,进程总是在运行,直到收到关机消息。但它们并不总是收集数据。实际的程序基本上用于异步数据收集、处理和显示,以提高速度因为Python线程不是并发的,所以要获得速度优势,唯一对我有意义的方法就是多个进程。是的,我意识到这是一个很短的时间,我有一个post.numpy.fft沿最后一个轴的默认值,所以我没有以同样的方式进行fft。真正的问题是,对于某些输入大小,numpy.fft非常有用慢。但在我的例子中,我可以将pad归零到接近2的幂次方(比如nfftpts=int(2**np.round(np.log2(nfftpts))),来解决这个问题。对于time.sleep(),我发现如果没有它,CPU的使用率会跳得很高。这只是一个测试程序,但在实际的、更复杂的程序中