版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Python多進(jìn)程并行編程實(shí)踐:以multiprocessing模塊為例專欄?Pytlab,Python中文社區(qū)專欄作者。主要從事科學(xué)計(jì)算與高性能計(jì)算領(lǐng)域的應(yīng)用,主要語(yǔ)言為Python,C,C++。熟悉數(shù)值算法(最優(yōu)化方法,蒙特卡洛算法等)與并行化算法(MPI,OpenMP等多線程以及多進(jìn)程并行化)以及python優(yōu)化方法,經(jīng)常使用C++給python寫擴(kuò)展。blog:github:/PytLab?—前言并行計(jì)算是使用并行計(jì)算機(jī)來(lái)減少單個(gè)計(jì)算問(wèn)題所需要的時(shí)間,我們可以通過(guò)利用編程語(yǔ)言顯式的說(shuō)明計(jì)算中的不同部分如何再不同的處理器上同時(shí)執(zhí)行來(lái)設(shè)計(jì)我們的并行程序,最終達(dá)到大幅度提升程序效率的目的。眾所周知,Python中的GIL限制了Python多線程并行對(duì)多核CPU的利用,但是我們?nèi)匀豢梢酝ㄟ^(guò)各種其他的方式來(lái)讓Python真正利用多核資源,例如通過(guò)C/C++擴(kuò)展來(lái)實(shí)現(xiàn)多線程/多進(jìn)程,以及直接利用Python的多進(jìn)程模塊multiprocessing來(lái)進(jìn)行多進(jìn)程編程。本文主要嘗試僅僅通過(guò)python內(nèi)置的multiprocessing模塊對(duì)自己的動(dòng)力學(xué)計(jì)算程序來(lái)進(jìn)行優(yōu)化和效率提升,其中:-實(shí)現(xiàn)了單機(jī)利用多核資源來(lái)實(shí)現(xiàn)并行并進(jìn)行加速對(duì)比-使用manager模塊實(shí)現(xiàn)了簡(jiǎn)單的多機(jī)的分布式計(jì)算本文并不是對(duì)Python的multiprocessing模塊的接口進(jìn)行翻譯介紹,需要熟悉multiprocessing的童鞋可以參考官方文檔/2/library/multiprocessing.html。正文最近想用自己的微觀動(dòng)力學(xué)程序進(jìn)行一系列的求解并將結(jié)果繪制成二維Map圖進(jìn)行可視化,這樣就需要對(duì)二維圖上的多個(gè)點(diǎn)進(jìn)行計(jì)算并將結(jié)果收集起來(lái)并進(jìn)行繪制,由于每個(gè)點(diǎn)都需要進(jìn)行一次ODE積分以及牛頓法求解方程組,因此要串行地繪制整張圖可能會(huì)遇到極低的效率問(wèn)題尤其是對(duì)參數(shù)進(jìn)行測(cè)試的時(shí)候,每畫(huà)一張圖都需要等很久的時(shí)間。其中繪制的二維圖中每個(gè)點(diǎn)都是獨(dú)立計(jì)算的,于是很自然而然的想到了進(jìn)行并行化處理。串行的原始版本由于腳本比較長(zhǎng),而且實(shí)現(xiàn)均為自己的程序,腳本的大致結(jié)構(gòu)如下,本質(zhì)是一個(gè)二重循環(huán),循環(huán)的變量分別為反應(yīng)物氣體(O2和CO)的分壓的值:整體過(guò)程就這么簡(jiǎn)單,我需要做的就是使用multiprocessing的接口來(lái)對(duì)這個(gè)二重循環(huán)進(jìn)行并行化。使用單核串行繪制100個(gè)點(diǎn)所需要的時(shí)間如下,總共花了240.76秒:二維map圖繪制的效果如下:進(jìn)行多進(jìn)程并行處理multiprocessing模塊multiprocessing模塊提供了類似threading模塊的接口,并對(duì)進(jìn)程的各種操作進(jìn)行了良好的封裝,提供了各種進(jìn)程間通信的接口例如Pipe,Queue等等,可以幫助我們實(shí)現(xiàn)進(jìn)程間的通信,同步等操作。使用Process類來(lái)動(dòng)態(tài)創(chuàng)建進(jìn)程實(shí)現(xiàn)并行multiprocessing模塊提供了Process能讓我們通過(guò)創(chuàng)建進(jìn)程對(duì)象并執(zhí)行該進(jìn)程對(duì)象的start方法來(lái)創(chuàng)建一個(gè)真正的進(jìn)程來(lái)執(zhí)行任務(wù),該接口類似threading模塊中的線程類Thread.但是當(dāng)被操作對(duì)象數(shù)目不大的時(shí)候可以使用Process動(dòng)態(tài)生成多個(gè)進(jìn)程,但是如果需要的進(jìn)程數(shù)一旦很多的時(shí)候,手動(dòng)限制進(jìn)程的數(shù)量以及處理不同進(jìn)程返回值會(huì)變得異常的繁瑣,因此這個(gè)時(shí)候我們需要使用進(jìn)程池來(lái)簡(jiǎn)化操作。使用進(jìn)程池來(lái)管理進(jìn)程multiprocessing模塊提供了一個(gè)進(jìn)程池Pool類,負(fù)責(zé)創(chuàng)建進(jìn)程池對(duì)象,并提供了一些方法來(lái)講運(yùn)算任務(wù)offload到不同的子進(jìn)程中執(zhí)行,并很方便的獲取返回值。例如我們現(xiàn)在要進(jìn)行的循環(huán)并行便很容易的將其實(shí)現(xiàn)。對(duì)于這里的單指令多數(shù)據(jù)流的并行,我們可以直接使用Pool.map()來(lái)將函數(shù)映射到參數(shù)列表中。Pool.map其實(shí)是map函數(shù)的并行版本,此函數(shù)將會(huì)阻塞直到所有進(jìn)程全部結(jié)束,而且此函數(shù)返回的結(jié)果順序仍然不變。首先,我先把針對(duì)每對(duì)分壓數(shù)據(jù)的處理過(guò)程封裝成一個(gè)函數(shù),這樣可以將函數(shù)對(duì)象傳遞給子進(jìn)程執(zhí)行。使用兩個(gè)核心進(jìn)行計(jì)算,計(jì)算時(shí)間從240.76s降到了148.61秒,加速比為1.62對(duì)不同核心的加速效果進(jìn)行測(cè)試為了查看使用不同核心數(shù)對(duì)程序效率的改善,我對(duì)不同的核心數(shù)和加速比進(jìn)行了測(cè)試?yán)L圖,效果如下:運(yùn)行核心數(shù)與程序運(yùn)行時(shí)間:運(yùn)行核心數(shù)與加速比:可見(jiàn),由于我外層循環(huán)只循環(huán)了10次因此使用的核心數(shù)超過(guò)10以后核心數(shù)的增加并不能對(duì)程序進(jìn)行加速,也就是多余的核心都浪費(fèi)掉了。使用manager實(shí)現(xiàn)簡(jiǎn)單的分布式計(jì)算前面使用了multiprocessing包提供的接口我們使用了再一臺(tái)機(jī)器上進(jìn)行多核心計(jì)算的并行處理,但是multiprocessing的用處還有更多,通過(guò)multiprocessing.managers模塊,我們可以實(shí)現(xiàn)簡(jiǎn)單的多機(jī)分布式并行計(jì)算,將計(jì)算任務(wù)分布到不同的計(jì)算機(jī)中運(yùn)行。Managers提供了另外的多進(jìn)程通信工具,他提供了在多臺(tái)計(jì)算機(jī)之間共享數(shù)據(jù)的接口和數(shù)據(jù)對(duì)象,這些數(shù)據(jù)對(duì)象全部都是通過(guò)代理類實(shí)現(xiàn)的,比如ListProxy和DictProxy等等,他們都實(shí)現(xiàn)了與原生list和dict相同的接口,但是他們可以通過(guò)網(wǎng)絡(luò)在不同計(jì)算機(jī)中的進(jìn)程中進(jìn)行共享。關(guān)于managers模塊的接口的詳細(xì)使用可以參考官方文檔:/2/library/multiprocessing.html#managers好了現(xiàn)在我們開(kāi)始嘗試將繪圖程序改造成可以在多臺(tái)計(jì)算機(jī)中分布式并行的程序。改造的主要思想是:1.使用一臺(tái)計(jì)算機(jī)作為服務(wù)端(server),此臺(tái)計(jì)算機(jī)通過(guò)一個(gè)Manager對(duì)象來(lái)管理共享對(duì)象,任務(wù)分配以及結(jié)果的接收,并再收集結(jié)果以后進(jìn)行后處理(繪制二維map圖)。2.其他多臺(tái)計(jì)算機(jī)可以作為客戶端來(lái)接收server的數(shù)據(jù)進(jìn)行計(jì)算,并將結(jié)果傳到共享數(shù)據(jù)中,讓server可以收集。同時(shí)再client端可以同時(shí)進(jìn)行上文所實(shí)現(xiàn)的多進(jìn)程并行來(lái)充分利用計(jì)算機(jī)的多核優(yōu)勢(shì)。大致可總結(jié)為下圖:服務(wù)進(jìn)程首先服務(wù)端需要一個(gè)manager對(duì)象來(lái)管理共享對(duì)象BaseManager.register是一個(gè)類方法,它可以將某種類型或者可調(diào)用的對(duì)象綁定到manager對(duì)象并共享到網(wǎng)絡(luò)中,使得其他在網(wǎng)絡(luò)中的計(jì)算機(jī)能夠獲取相應(yīng)的對(duì)象。例如,JobManager.register('get_jobid_queue',callable=lambda:jobid_queue)我就將一個(gè)返回任務(wù)隊(duì)列的函數(shù)對(duì)象同manager對(duì)象綁定并共享到網(wǎng)絡(luò)中,這樣在網(wǎng)絡(luò)中的進(jìn)程就可以通過(guò)自己的manager對(duì)象的get_jobid_queue方法得到相同的隊(duì)列,這樣便實(shí)現(xiàn)了數(shù)據(jù)的共享.創(chuàng)建manager對(duì)象的時(shí)候需要兩個(gè)參數(shù),address,便是manager所在的ip以及用于監(jiān)聽(tīng)與服務(wù)端連接的端口號(hào),例如我如果是在內(nèi)網(wǎng)中的地址的5000端口進(jìn)行監(jiān)聽(tīng),那么此參數(shù)可以是(',5000)`authkey,顧名思義,就是一個(gè)認(rèn)證碼,用于驗(yàn)證客戶端時(shí)候可以連接到服務(wù)端,此參數(shù)必須是一個(gè)字符串對(duì)象.進(jìn)行任務(wù)分配上面我們將一個(gè)任務(wù)隊(duì)列綁定到了manager對(duì)象中,現(xiàn)在我需要將隊(duì)列進(jìn)行填充,這樣才能將任務(wù)發(fā)放到不同的客戶端來(lái)進(jìn)行并行執(zhí)行。這里所謂的任務(wù)其實(shí)就是相應(yīng)參數(shù)在list中的index值,這樣不同計(jì)算機(jī)中得到的結(jié)果可以按照相應(yīng)的index將結(jié)果填入到結(jié)果列表中,這樣服務(wù)端就能在共享的網(wǎng)絡(luò)中收集各個(gè)計(jì)算機(jī)計(jì)算的結(jié)果。啟動(dòng)服務(wù)端進(jìn)行監(jiān)聽(tīng)任務(wù)進(jìn)程服務(wù)進(jìn)程負(fù)責(zé)進(jìn)行簡(jiǎn)單的任務(wù)分配和調(diào)度,任務(wù)進(jìn)程則只負(fù)責(zé)獲取任務(wù)并進(jìn)行計(jì)算處理。在任務(wù)進(jìn)程(客戶端)中基本代碼與我們上面單機(jī)中的多核運(yùn)行的腳本基本相同(因?yàn)槎际峭粋€(gè)函數(shù)處理不同的數(shù)據(jù)),但是我們也需要為客戶端創(chuàng)建一個(gè)manager來(lái)進(jìn)行任務(wù)的獲取和返回。在客戶端我們?nèi)匀豢梢远噙M(jìn)程利用多核資源來(lái)加速計(jì)算。下面我將在3臺(tái)在同一局域網(wǎng)中的電腦來(lái)進(jìn)行簡(jiǎn)單的分布式計(jì)算測(cè)試,-其中一臺(tái)是實(shí)驗(yàn)室器群中的管理節(jié)點(diǎn),內(nèi)網(wǎng)ip為45-另一臺(tái)為集群中的一個(gè)節(jié)點(diǎn),共有12個(gè)核心-最后一臺(tái)為自己的本本,4個(gè)核心先在服務(wù)端運(yùn)行服務(wù)腳本進(jìn)行任務(wù)分配和監(jiān)聽(tīng):pythonserver.py在兩個(gè)客戶端運(yùn)行任務(wù)腳本來(lái)獲取任務(wù)隊(duì)列中的任務(wù)并執(zhí)行pythonworker.py當(dāng)任務(wù)隊(duì)列為空且任務(wù)完成時(shí),任務(wù)進(jìn)程終止;當(dāng)結(jié)果列表中的結(jié)果收集完畢時(shí),服務(wù)進(jìn)程也會(huì)終止。執(zhí)行結(jié)果如下圖:上面的panel為服務(wù)端監(jiān)聽(tīng),左下為自己的筆記本運(yùn)行結(jié)果,右下panel為集群中的其中一個(gè)節(jié)點(diǎn)??梢?jiàn)運(yùn)行時(shí)間為56.86s,無(wú)奈,是我的本子脫了后腿(-_-!)總結(jié)本文通過(guò)python內(nèi)置模塊multiprocessing實(shí)現(xiàn)了單機(jī)內(nèi)多核并行以及簡(jiǎn)單的多臺(tái)計(jì)算機(jī)的分布式并行計(jì)算,multiprocessing為我們提供了封裝良好并且友好的接口來(lái)使我們的Python程序更方面利用多核資源加速自己的計(jì)算程序,希望能對(duì)使用python實(shí)現(xiàn)并行話的童鞋有所幫助。參考/2/library/multiprocessing.html分布式進(jìn)程-廖雪峰的官方網(wǎng)站ARTICLES近期熱門文章⊙生成器:關(guān)于生成器的那些事兒⊙爬蟲(chóng)代理:如何構(gòu)建爬蟲(chóng)代理服務(wù)⊙地理編碼:怎樣用Python實(shí)現(xiàn)地理編碼⊙nginx日志:使用Python分析nginx日志⊙淘寶女郎:一個(gè)批量抓取淘女郎寫真圖片的爬蟲(chóng)⊙IP代理池:突破
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年滬科版八年級(jí)歷史上冊(cè)階段測(cè)試試卷含答案
- 2025年北師大版九年級(jí)地理下冊(cè)月考試卷含答案
- 2025年度特色民宿門面房租賃與民宿經(jīng)營(yíng)合同4篇
- 二零二五版旅游特色餐飲服務(wù)采購(gòu)合同4篇
- 2025年牛津譯林版九年級(jí)歷史下冊(cè)月考試卷含答案
- 2025年蘇教版選擇性必修3歷史下冊(cè)月考試卷含答案
- 2025年浙科版九年級(jí)物理上冊(cè)階段測(cè)試試卷含答案
- 二零二五版農(nóng)機(jī)作業(yè)租賃與農(nóng)業(yè)人才培養(yǎng)合作合同4篇
- 2024 年四川公務(wù)員行測(cè)(C 類)真題及答 案
- 二零二五年度沐足行業(yè)員工權(quán)益保障合同范本4篇
- 2025年度杭州市固廢處理與資源化利用合同3篇
- 部編版二年級(jí)下冊(cè)《道德與法治》教案及反思(更新)
- 充電樁項(xiàng)目運(yùn)營(yíng)方案
- 退休人員出國(guó)探親申請(qǐng)書(shū)
- 傷殘撫恤管理辦法實(shí)施細(xì)則
- 高中物理競(jìng)賽真題分類匯編 4 光學(xué) (學(xué)生版+解析版50題)
- 西方經(jīng)濟(jì)學(xué)-高鴻業(yè)-筆記
- 幼兒園美術(shù)教育研究策略國(guó)內(nèi)外
- 物業(yè)公司介紹
- 2024屆河南省五市高三第一次聯(lián)考英語(yǔ)試題及答案
- 【永輝超市公司員工招聘問(wèn)題及優(yōu)化(12000字論文)】
評(píng)論
0/150
提交評(píng)論