這其實是我之前問題的延續: 降低嵌套回圈的時間復雜度
我想為我的 Pearson 的 r 演算法實作多執行緒。在這里,我將矩陣 X 劃分為 n/txn 并將向量 y 劃分為 n/tx 1 并將每個段饋送到執行緒中。我目前正在使用多處理庫中的 ThreadPool 作為 python 執行緒庫的替代品。這是因為在測驗程序中我注意到 Threading 并沒有真正同時運行執行緒。在互聯網上進一步搜索后,這是由于 GIL(全域解釋器鎖定)。他們建議使用多處理庫,下面的代碼是我迄今為止所做的。
pearson-cor:該演算法旨在解決 Pearson 的 r,其中函式接受矩陣 X、向量 y 和 (m, n) 大小。您可能會在上面的鏈接中看到代碼。
我在這里擔心的是,隨著執行緒數量的增加,處理時間仍然會增加(另請參見下面的示例輸出)。從我的測驗中可以看出,時間從執行緒 = 2 減少到執行緒 = 4,并開始從執行緒 = 8 再次增加到 64。雖然它們仍然比單執行緒的要好,但我希望它們會減少同時處理更多的計算。
我想知道為什么會這樣。我是多處理的新手,我上周才開始學習這個。我的實施是否有任何錯誤或缺失?這仍然與 GIL 有關嗎?如果是這樣,您對如何解決這個問題以更有效地實作多執行緒有什么建議嗎?
n = int(input("n = "))
t = int(input("t = "))
correct_rs = []
y = np.random.randint(0,100, size = n)
X = np.random.randint(0,100,size = (n,n))
split_y = np.array_split(y, t)
split_x = []
for i in range(n):
split_x.append(np.array_split(X[i], t))
for i in range(n):
threads = [None] * t
ret = []
for j in range(t):
pool = ThreadPool(processes=t)
threads[j] = pool.apply_async(pearson_cor, args=(split_x[i][j], split_y[j]))
ret.append(threads[j].get())
1 = 30.79026460647583
2 = 19.61565899848938
**4 = 22.66206121444702**
8 = 26.578197240829468
16 = 27.43799901008606
32 = 29.007505416870117
64 = 29.55176091194153
1 = 82.63879776000977
2 = 71.86883449554443
4 = 66.2829954624176
**8 = 72.7975389957428**
16 = 74.40859937667847
32 = 79.7437674999237
64 = 82.5101261138916
1 = 3.117418050765991
2 = 2.9685776233673096
4 = 2.442412853240967
**8 = 2.6580233573913574**
16 = 2.7630186080932617
32 = 2.747586727142334
64 = 2.768829345703125
uj5u.com熱心網友回復:
要考慮的一件事是 CPU 抖動(https://stackoverflow.com/a/20842853/6014330)。根據不同的事情,CPU 將花費更多時間來交換實際運行的代碼。
另一件事:如果您的 CPU 只有 8 個可用執行緒并且您嘗試使用 64 個執行緒,那么您只需要 64 個執行緒并在它們之間切換 8 次。您可以獲得的最佳效果是與您的 CPU 擁有的執行緒數量相匹配。再多的就是浪費了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/513748.html
標籤:Python多线程
上一篇:在bash腳本中并行運行命令
下一篇:生產者消費者Java|同步問題
