簡體   English   中英

我如何改善我的多線程使用率以減少運行時間,python

[英]how can i improve my multi threading usage to decrease run time, python

機器信息

cpu_num 8 CPUs
cpu_speed   2826 MHz
mem_total   8173980 KB
swap_total  16777208 KB

標桿管理

當我增加線程數時,性能會有所提高(數字是10次運行的平均值)

Number of Threads   Time
1                   1.322187
2                   0.789151
3                   0.72232
5                   0.613691
10                 0.558912
40                 0.531966

在運行代碼時從頂部快照

top - 01:40:42 up 7 days, 13:24,  9 users,  load average: 0.34, 0.22, 0.27
Tasks: 364 total,   2 running, 362 sleeping,   0 stopped,   0 zombie
Cpu(s): 28.2%us,  0.1%sy,  0.0%ni, 71.5%id,  0.0%wa,  0.1%hi,  0.0%si,  0.0%st
Mem:   8173980k total,  7437664k used,   736316k free,   224748k buffers
Swap: 16777208k total,   149244k used, 16627964k free,  6374428k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                              
20365 ben.long  15   0  723m 208m 4224 S 226.2  2.6   0:37.28 python26                            
19948 ben.long  15   0 10996 1256  764 R  0.7  0.0   0:03.84 top                                                                  4420 ben.long  15   0  106m 3776 1360 R  0.0  0.0   0:03.06 sshd                                                                
 4421 ben.long  15   0 64320 1628 1180 S  0.0  0.0   0:00.07 bash                                                                 4423 ben.long  15   0 64320 1596 1180 S  0.0  0.0   0:00.03 bash                                                                
19949 ben.long  15   0 64308 1552 1136 S  0.0  0.0   0:00.01 bash 

剝離的代碼看起來像

from threading import Thread

class testit(Thread):
   def __init__ (self,i):
      Thread.__init__(self)
   def run(self):
      some_task()#do processor heavy task

num_threads_to_use = 10
thread_list = []

for i in range (0,num_threads_to_use):
   current = testit(i)
   thread_list.append(current)
   current.start()

for thread in thread_list:
   thread.join()

問題

  1. 我應該使用多處理模塊而不是線程模塊嗎?
  2. 有沒有辦法改善下面的解決方案?

隨着線程數量接近核心數量,性能非線性非線性增長的原因可能在於:

some_task()#do processor heavy task  

GIL是圍繞I / O繁重的操作發布的; 如果some_task()受CPU限制,那么您當時僅占用一個GIL線程,從而犧牲了線程的優勢(並可能在太多上下文切換中浪費時間)。

http://docs.python.org/c-api/init.html

Python解釋器不是完全線程安全的。 為了支持多線程Python程序,有一個全局鎖,稱為全局解釋器鎖或GIL,必須先由當前線程持有,然后才能安全地訪問Python對象。 如果沒有鎖,即使是最簡單的操作也可能在多線程程序中引起問題:例如,當兩個線程同時增加同一對象的引用計數時,引用計數最終只能增加一次而不是兩次。

因此,存在這樣的規則,即只有已獲得全局解釋器鎖的線程才可以在Python對象上操作或調用Python / C API函數。 為了支持多線程Python程序,解釋器會定期釋放並重新獲取鎖-默認情況下,每100個字節碼指令(可以通過sys.setcheckinterval()進行更改)。 鎖定也被釋放並重新獲得,這可能會阻止潛在的阻塞I / O操作(如讀取或寫入文件),以便在請求I / O的線程正在等待I / O操作完成的同時運行其他線程。

我可能是錯的,但是我猜想線程共享相同的GIL,而進程卻沒有。 請嘗試使用多處理模塊。

如果您正在執行一些CPU密集型任務,則python中唯一要加快速度的方法是使用多個進程。

其他選擇是

  • 使用不同的python實現,例如IronPythonJython
  • 將CPU密集型代碼編寫為C模塊

暫無
暫無

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

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