簡體   English   中英

盡管有 GIL,多線程仍可加速 CPU 密集型任務

[英]Multithreading accelerates CPU bound tasks despite of GIL

我最近在 python 中了解了 GIL。 我正在做一些基准測試,發現多線程實際上確實提高了性能。 我比較了不使用任何內部多線程的元素 NumPy 操作。 在第一個測試中,我從 for 循環中依次調用 function 32 次。 在第二種情況下,我使用多線程。 但是如果 GIL 正在工作,在第二種情況下,一次應該只有 1 個線程處於活動狀態,因此執行時間應該大致相等(由於多線程開銷,在第二種情況下甚至更糟)。 這不是我觀察到的。

import os
import threading
import numpy as np, time

def elemntwiseoperations(a,b):
    np.exp(a)+np.sin(b)
        
N=1024
a=np.random.rand(N,N)
b=np.random.rand(N,N)


NoTasks=32

start_time = time.time()
for i in range(NoTasks):
    elemntwiseoperations(a,b)
print("Execution time for {} tasks: {} seconds, {} seconds per task".format(NoTasks,time.time() - start_time,(time.time() - start_time)/NoTasks))

threads=[]
start_time = time.time()
for i in range(NoTasks):
    x = threading.Thread(target=elemntwiseoperations,name=''.format(i),args=(a,b))
    x.start()
    threads.append(x)
    
for process in threads:
    process.join()

print("Execution time for {} tasks: {} seconds, {} seconds per task".format(NoTasks,time.time() - start_time,(time.time() - start_time)/NoTasks))

Output:

Execution time for 32 tasks: 0.5654711723327637 seconds, 0.01767103374004364 seconds per task
Execution time for 32 tasks: 0.17153215408325195 seconds, 0.005360409617424011 seconds per task

PS MAC 操作系統,python 3.7.6,Cpython 實現。

因此,我目前的最佳猜測如下:在第一種情況下,一個線程按順序啟動 C 例程。 在開始新的之前,它會等待每個完成。 由於我只使用 numpy 中未並行化的元素操作,因此整個過程只涉及一個線程。

在第二種情況下,我調用了 32 個虛擬線程,每個都受 GIL 影響。 第一個線程啟動 C 例程並將 GIL 控制權交給第二個線程,然后第二個線程啟動 C 例程並將控制權交給第三個線程,依此類推。 盡管 C 例程不是同時調用的,但它們都是同時執行的,因為 C 不受 GIL 影響。

我不知道如何實際檢查它,但這是我在閱讀了幾篇關於 GIL 的 python 博客后理解的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM