python多核處理器算力浪費問題解決
前言
我們都知道python因為其GIL鎖導(dǎo)致每一個線程被綁定到一個核上,導(dǎo)致python無法通過線程實現(xiàn)真正的平行計算。從而導(dǎo)致大量的核算力的浪費。但是
concurrent.futures模塊,可以利用multiprocessing實現(xiàn)真正的平行計算。
但是在提高python的計算性能前,首先要明白自己的程序目前是什么類型? 對于不同類型的程序,如果安裝下述方法進行改造,可能效率并不會提高。
IO密集型:讀取文件,讀取網(wǎng)絡(luò)套接字頻繁。
計算密集型:大量消耗CPU的數(shù)學(xué)與邏輯運算,也就是我們這里說的平行計算。
IO密集型
可以使用asyncio 來進行優(yōu)化,jit的原理是編譯為機器碼執(zhí)行,但是io中可能會存在異常字符,所以也不推薦使用,當(dāng)然在存在多態(tài)主機的情況下,可以采用分布式編程來提高效率,或者過concurrent.futures模塊來實現(xiàn)。
詳情請看下一篇博文 python 性能的優(yōu)化
計算密集型
當(dāng)然我們可以使用jit,分布式編程,python 調(diào)用c編程來優(yōu)化性能,但是要充分利用計算機的核數(shù),可以通過concurrent.futures模塊來實現(xiàn),其在實現(xiàn)提高并行計算能力時時通過多進程實現(xiàn)。
該concurrent.futures模塊提供了一個用于異步執(zhí)行callables的高級接口。
可以使用線程,使用ThreadPoolExecutor或單獨的進程 來執(zhí)行異步執(zhí)行 ProcessPoolExecutor。兩者都實現(xiàn)相同的接口,由抽象Executor類定義。
concurrent.futures會以子進程的形式,平行的運行多個python解釋器,從而令python程序可以利用多核CPU來提升執(zhí)行速度。由于子進程與主解釋器相分離,所以他們的全局解釋器鎖也是相互獨立的。每個子進程都能夠完整的使用一個CPU內(nèi)核。
def gcd(pair): a, b = pair low = min(a, b) for i in range(low, 0, -1): if a % i == 0 and b % i == 0: return i numbers = [ (1963309, 2265973), (1879675, 2493670), (2030677, 3814172), (1551645, 2229620), (1988912, 4736670), (2198964, 7876293) ] import time start = time.time() results = list(map(gcd, numbers)) end = time.time() print 'Took %.3f seconds.' % (end - start) Took 2.507 seconds.
import time from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, Executor start = time.time() pool = ProcessPoolExecutor(max_workers=2) results = list(pool.map(gcd, numbers)) end = time.time() print 'Took %.3f seconds.' % (end - start) Took 1.861 seconds.
在兩個CPU核心的機器上運行多進程程序,比其他兩個版本都快。這是因為,ProcessPoolExecutor類會利用multiprocessing模塊所提供的底層機制,完成下列操作:
1)把numbers列表中的每一項輸入數(shù)據(jù)都傳給map。
2)用pickle模塊對數(shù)據(jù)進行序列化,將其變成二進制形式。
3)通過本地套接字,將序列化之后的數(shù)據(jù)從煮解釋器所在的進程,發(fā)送到子解釋器所在的進程。
4)在子進程中,用pickle對二進制數(shù)據(jù)進行反序列化,將其還原成python對象。
5)引入包含gcd函數(shù)的python模塊。
6)各個子進程并行的對各自的輸入數(shù)據(jù)進行計算。
7)對運行的結(jié)果進行序列化操作,將其轉(zhuǎn)變成字節(jié)。
8)將這些字節(jié)通過socket復(fù)制到主進程之中。
9)主進程對這些字節(jié)執(zhí)行反序列化操作,將其還原成python對象。
10)最后,把每個子進程所求出的計算結(jié)果合并到一份列表之中,并返回給調(diào)用者。
multiprocessing開銷比較大,原因就在于:主進程和子進程之間通信,必須進行序列化和反序列化的操作。
submit(fn,* args,** kwargs ) 將可調(diào)用的fn調(diào)度為執(zhí)行, 并返回表示可調(diào)用執(zhí)行的對象。
fn(*args **kwargs)Future with ThreadPoolExecutor(max_workers=1) as executor: future = executor.submit(pow, 323, 1235) print(future.result()) map(func,* iterables,timeout = None,chunksize = 1 )
與以下類似:map(func, *iterables)
在iterables收集立即而不是懶洋洋地; func以異步方式執(zhí)行,并且可以同時對func進行多次調(diào)用 。 返回的迭代器引發(fā)一個concurrent.futures.TimeoutError if next()被調(diào)用,并且在從原始調(diào)用到超時秒后結(jié)果不可用Executor.map()。 timeout可以是int或float。如果未指定 超時None,則等待時間沒有限制。
如果func調(diào)用引發(fā)異常,則在從迭代器檢索其值時將引發(fā)該異常。
使用時ProcessPoolExecutor,此方法將iterables切割 為多個塊,并將其作為單獨的任務(wù)提交給池??梢酝ㄟ^將chunksize設(shè)置為正整數(shù)來指定這些塊的(近似)大小。對于很長的iterables,采用大值CHUNKSIZE可以顯著改善性能相比的1.默認(rèn)大小 ThreadPoolExecutor,CHUNKSIZE沒有效果。
在3.5版中更改:添加了chunksize參數(shù)。
shutdown(wait = True ) 向執(zhí)行者發(fā)出信號,表示當(dāng)目前待處理的期貨執(zhí)行完畢時,它應(yīng)該釋放它正在使用的任何資源。關(guān)機后撥打電話Executor.submit()和撥打電話 Executor.map()將會提出RuntimeError。
如果等待是True那么這種方法將不會返回,直到所有懸而未決的期貨執(zhí)行完畢,并與執(zhí)行相關(guān)的資源已被釋放。如果等待,F(xiàn)alse那么此方法將立即返回,并且當(dāng)執(zhí)行所有未決期貨時,將釋放與執(zhí)行程序關(guān)聯(lián)的資源。無論wait的值如何,整個Python程序都不會退出,直到所有待處理的期貨都執(zhí)行完畢。
如果使用with語句,則可以避免必須顯式調(diào)用此方法 ,該語句將關(guān)閉Executor (等待,就像Executor.shutdown()使用wait set 調(diào)用一樣True):
import shutil with ThreadPoolExecutor(max_workers=4) as e: e.submit(shutil.copy, 'src1.txt', 'dest1.txt') e.submit(shutil.copy, 'src2.txt', 'dest2.txt') e.submit(shutil.copy, 'src3.txt', 'dest3.txt') e.submit(shutil.copy, 'src4.txt', 'dest4.txt')
以上就是python多核處理器算力浪費現(xiàn)象處理的詳細(xì)內(nèi)容,更多關(guān)于python多核處理器算力浪費的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python光學(xué)仿真面向?qū)ο蠊鈱W(xué)元件類的實現(xiàn)
這篇文章主要為大家介紹了python光學(xué)仿真面向?qū)ο蠊鈱W(xué)元件類的實現(xiàn)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2021-10-10Python數(shù)據(jù)分析之?Pandas?Dataframe合并和去重操作
這篇文章主要介紹了Python數(shù)據(jù)分析之?Pandas?Dataframe合并和去重操作,文章基于python的相關(guān)資料展開詳細(xì)的內(nèi)容介紹,需要的小伙伴可以參考一下2022-05-05使用Python實現(xiàn)查找PDF中的指定文本并高亮顯示
在處理大量PDF文檔時,有時我們需要快速找到特定的文本信息,本文將提供三個Python示例來幫助你在PDF文件中快速查找并高亮指定的文本,希望對大家有所幫助2024-03-03Python機器學(xué)習(xí)之實現(xiàn)模糊照片人臉恢復(fù)清晰
GFPGAN是騰訊開源的人臉修復(fù)算法,它利用預(yù)先訓(xùn)練好的面部?GAN(如?StyleGAN2)中封裝的豐富和多樣的先驗因素進行盲臉?(blind?face)修復(fù)。這篇文章主要為大家介紹通過GFPGAN實現(xiàn)模糊照片人臉恢復(fù)清晰,需要的朋友可以參考一下2021-12-12Pyecharts 中Geo函數(shù)常用參數(shù)的用法說明
這篇文章主要介紹了Pyecharts 中Geo函數(shù)常用參數(shù)的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02使用python-pptx包批量修改ppt格式的實現(xiàn)
今天小編就為大家分享一篇使用python-pptx包批量修改ppt格式的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02通過Python的filestools庫給圖片添加全圖水印的示例詳解
這篇文章主要介紹了通過Python的filestools庫給圖片添加全圖水印,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04ansible-playbook實現(xiàn)自動部署KVM及安裝python3的詳細(xì)教程
這篇文章主要介紹了ansible-playbook實現(xiàn)自動部署KVM及安裝python3的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05