繁体   English   中英

如何使用多线程python减少执行时间

[英]How to decrease time of execution using multi-threading python

我正在执行DCT(在Raspberry Pi中)。 我已将图像分成8x8的块。 最初,我在嵌套的for循环中执行DCT(无多线程)。 我观察到,一张512x512的图像大约需要18秒。 但是,这是带有多线程的代码

   #!/usr/bin/env python

from __future__ import print_function,division
import time
start_time = time.time()
import cv2
import numpy as np
import sys
import pylab as plt
import threading
import Queue

from numpy import empty,arange,exp,real,imag,pi
from numpy.fft import rfft,irfft
from pprint import pprint 

queue = Queue.Queue()

if len(sys.argv)>1:
        im = cv2.imread(sys.argv[1])
else :
        im = cv2.imread('baboon.jpg')

        im = cv2.cvtColor(im,  cv2.COLOR_BGR2GRAY)
        h, w = im.shape[:2]
        DF = np.zeros((h,w))
        Nb=8

def dct2(y):
    M = y.shape[0]
    N = y.shape[1]
    a = empty([M,N],float)
    b = empty([M,N],float)

    for i in range(M):
        a[i,:] = dct(y[i,:])
    for j in range(N):
        b[:,j] = dct(a[:,j])

    queue.put(b)

def dct(y):
    N = len(y)
    y2 = empty(2*N,float)
    y2[:N] = y[:]
    y2[N:] = y[::-1]

    c = rfft(y2)
    phi = exp(-1j*pi*arange(N)/(2*N))
    return real(phi*c[:N])

def Main():
    jobs = []
    for row in range(0, h, Nb):
            for col in range(0, w, Nb):
                            f =  im[(row):(row+Nb), (col):(col+Nb)]
                            thread = threading.Thread(target=dct2(f))
                            jobs.append(thread)
                            df = queue.get()
                            DF[row:row+Nb, col:col+Nb] = df 

    for j in jobs:
            j.start()


    for j in jobs:
            j.join()


if __name__ == "__main__":
        Main()


cv2.imwrite('dct_img.jpg', DF)
print("--- %s seconds ---" % (time.time() - start_time))
plt.imshow(DF1, cmap = 'Greys')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

使用多个线程后,此代码大约需要25秒钟才能执行。 怎么了? 我是否错误地实现了多线程? 我想尽可能减少执行DCT的时间(1-5秒)。 有什么建议么?

还有其他任何可以显着减少执行和处理时间的概念或方法(我已经阅读过有关多处理的文章)?

由于GIL,您的所有线程都是按顺序执行的(不是并行执行的)。 因此,您可能需要切换到多处理 另一个选择是构建numba ,它可以大大提高常规python代码的速度,也可以解锁GIL

在Python中,仅在混合IO和CPU任务时才应使用多线程性能。

对于您的问题,您应该使用多重处理。

也许其他海报关于GIL是正确的。 但是OpenCV以及Numpy都发布了GIL,因此我至少希望多线程解决方案能够加快速度。

我将看看您同时创建了多少个线程。 自从您为每8 x 8像素的子图片启动一个图片以来,可能有很多。 (每次从cpu上取下一个线程并替换为另一个线程,都会产生少量开销,如果线程很多,总的来说,这很明显)

如果是这种情况,您可能不立即启动所有内核,而是仅启动与您拥有的cpu内核一样多的内核(少了几个,少了一些……只是实验),从而获得了性能,并且仅在完成一个内核后才启动下一个线程。

看看答案, 这个问题如何以最小的努力做到这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM