为什么线程不能加快numpy数组的迭代速度?

2024-07-04 08:07:19 发布

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

我的问题是关于python中的多线程。我正在研究的问题是,从1000万个数组中找到与给定数组80%相似(长度为64)且长度相同的数组。问题是,虽然当我在while循环中线性迭代时,我的代码在12.148秒内执行,但当我使用多线程时,它不会在至少28-30秒内执行。下面是两种实现。任何建议感谢,请启发我,为什么它使它在这种情况下慢多线程? 第一个代码:

import timeit
import numpy as np

ph = np.load('newDataPhoto.npy')
myPhoto1 = np.array([ 1. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0.
,  0. , 1. , 1. , 0. , 1. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 1.
,  1. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 0. ])



start = timeit.default_timer()

kk=0
i=0
while i< 10000000:
    u = np.count_nonzero(ph[i] != myPhoto1)
    if  u <= 14:
        kk+=1
    i+=1

print(kk)

stop = timeit.default_timer()
print stop-start

第二个(多线程):

from threading import Thread
import numpy as np
import timeit

start = timeit.default_timer()
ph = np.load('newDataPhoto.npy')
pc = np.load('newDataPopCount.npy')

myPhoto1 = np.array([ 1. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0.
,  0. , 1. , 1. , 0. , 1. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 1.
,  1. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 0. ])

def hamming_dist(left, right, name):
    global kk
    start = timeit.default_timer()
    while left<=right:
        if(np.count_nonzero(ph[left] != myPhoto1)<=14):
            kk+=1
        left+=1

    stop=timeit.default_timer()
    print name
    print stop-start

def Main():
    global kk
    kk=0
    t1 = Thread(target=hamming_dist, args=(0,2500000, 't1'))
    t2 = Thread(target=hamming_dist, args=(2500001, 5000000, 't2'))
    t3 = Thread(target=hamming_dist, args=(5000001, 7500000,'t3'))
    t4 = Thread(target=hamming_dist, args=(7500001, 9999999, 't4'))

    t1.start()
    t2.start()
    t3.start()
    t4.start()

    print ('main done')

if __name__ == "__main__":
    Main()

其输出顺序如下:

38
12.148679018 
#####
main done
t4
26.4695241451
t2
27.4959039688
t3
27.5113890171
t1
27.5896160603

Tags: importdefaultdistnpleftthreadstartph
1条回答
网友
1楼 · 发布于 2024-07-04 08:07:19

我解决了这个问题。我发现线程被GIL阻塞了,GIL从不允许使用比当前处理器更多的线程。然而,使用多处理模块是可行的。以下是我所做的修改:

import numpy as np
import multiprocessing
import timeit

start = timeit.default_timer()
ph = np.load('newDataPhoto.npy')
pc = np.load('newDataPopCount.npy')

myPhoto1 = np.array([ 1. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0.
,  0. , 1. , 1. , 0. , 1. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 1. , 1. , 0. , 0. , 1. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 1.
,  1. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 0. ])

def hamming_dist(left, right, name):
    global kk
    start = timeit.default_timer()
    while left<=right:
        if(np.count_nonzero(ph[left] != myPhoto1)<=14):
            kk+=1
        left+=1

    stop=timeit.default_timer()
    print name
    print stop-start

def Main():
    global kk
    kk=0
    t1 = multiprocessing.Process(target=hamming_dist, args=(0,2500000, 't1'))
    t2 = multiprocessing.Process(target=hamming_dist, args=(2500001, 5000000, 't2'))
    t3 = multiprocessing.Process(target=hamming_dist, args=(5000001, 7500000,'t3'))
    t4 = multiprocessing.Process(target=hamming_dist, args=(7500001, 9999999, 't4'))

    t1.start()
    t2.start()
    t3.start()
    t4.start()

    print ('main done')

if __name__ == "__main__":
    Main()

相关问题 更多 >

    热门问题