2 回答

TA貢獻1777條經驗 獲得超3個贊
正如您提到的,Python 有一個“全局解釋器鎖”(GIL),可以防止Python 代碼的兩個線程同時運行。多線程可以加速 IO 密集型任務的原因是 Python 在偵聽網絡套接字或等待磁盤讀取時釋放 GIL。因此,GIL 不會阻止計算機同時完成兩批工作,它會阻止同一 Python 進程中的兩個 Python 線程同時運行。
在您的示例中,您使用 numpy 和 scipy。這些主要是用 C 編寫的,并利用用 C/Fortran/Assembly 編寫的庫(BLAS、LAPACK 等)。當您對 numpy 數組執行操作時,類似于監聽套接字,因為GIL 被釋放。當 GIL 被釋放并且 numpy 數組操作被調用時,numpy 開始決定如何執行工作。如果需要,它可以生成其他線程或進程,并且它調用的 BLAS 子例程可能會生成其他線程。如果您想從源代碼編譯 numpy,則可以在構建時準確配置是否/如何完成此操作。
因此,總而言之,您已經找到了規則的例外。如果您僅使用純 Python 函數重復該實驗,您將得到完全不同的結果。

TA貢獻1811條經驗 獲得超5個贊
Python 線程是真正的線程,只是解釋器中不能同時存在兩個線程(這就是 GIL 的含義)。代碼的本機部分可以很好地并行運行,而不會在多個線程上發生爭用,只有當深入解釋器時,它們才必須在彼此之間進行序列化。
僅將所有 CPU 核心加載到 100% 的事實并不能證明您正在“高效”使用機器。您需要確保 CPU 使用率不是由上下文切換引起的。
如果您切換到多處理而不是線程(它們非常相似),則不必雙重猜測,但是在線程之間傳遞時必須對有效負載進行封送。
所以無論如何都需要測量一切。
添加回答
舉報