python下同樣代碼,多核多線程為什麼比單核多線程慢很多?

來源:互聯網
上載者:User
有一個疑問:python的多線程效能問題,本來以為是GIL的競爭導致的多線程下特別慢。但是在單cpu上的多線程效能下降並不明顯,但是同樣的代碼到了多核上之後,效能下降特別明顯。那麼在多核下的多線程效能明顯下降的原因是cpu的頻繁切換導致的嗎? 主要問題應該是:【多CPU之間的頻繁切換會有消耗嗎?】
【備忘】:已經明白了為什麼需要GIL以及GIL導致的同一時間只能執行一個線程。想問的問題是python在多cpu之間的執行細節。

回複內容:

python 由於有全域解譯器鎖,線程不支援多cpu。如果想支援多cpu,請用多進程。

Python的GIL
  • CPython的線程是作業系統的原生線程。在Linux上為pthread,在Windows上為Win thread,完全由作業系統調度線程的執行。一個python解譯器進程內有一條主線程,以及多條使用者程式的執行線程。即使在多核CPU平台上,由於GIL的存在,所以禁止多線程的並存執行。
  • Python解譯器進程內的多線程是合作多任務方式執行。當一個線程遇到I/O任務時,將釋放GIL。計算密集型(CPU-bound)的線程在執行大約100次解譯器的計步(ticks)時,將釋放GIL。計步(ticks)可粗略看作Python虛擬機器的指令。計步實際上與時間片長度無關。可以通過sys.setcheckinterval()設定計步長度。
  • 在單核CPU上,數百次的間隔檢查才會導致一次線程切換。在多核CPU上,存在嚴重的線程顛簸(thrashing)。
  • Python 3.2開始使用新的GIL。在新的GIL實現中,用一個固定的逾時時間來指示當前的線程放棄全域鎖。在當前線程保持這個鎖,且其他線程請求這個鎖的時候,當前線程就會在5ms後被強制釋放掉這個鎖。
  • 可以建立獨立的進程來實現並行化。Python 2.6引進了multiprocessing這個多進程包。或者把關鍵區段用C/C++寫成 Python 擴充,通過cytpes使Python程式直接調用C語言編譯的動態庫的匯出函數。
最近摸索出一個新辦法繞過gil限制:使用python裡面的qt庫(叫pyqt),qthread類建立以後,會在下層調用c++的qt庫建立線程。python gil的規則是進入其他語言代碼編寫的庫前會釋放gil,因此在qthread的run函數(新線程的主函數)裡面是另外一個新開的python.exe線程,不受gil限制。自己研究了一下:多核多線程比單核多線程更差,原因是單核下多線程,每次釋放GIL,喚醒的那個線程都能擷取到GIL鎖,所以能夠無縫執行,但多核下,CPU0釋放GIL後,其他CPU上的線程都會進行競爭,但GIL可能會馬上又被CPU0拿到,導致其他幾個CPU上被喚醒後的線程會醒著等待直到切換時間結束後又進入待調度狀態,導致線程顛簸,降低了系統效率。不知道這樣解釋對不對。望有人能指正
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.