黄视频网站在线免费观看-黄视频网站在线看-黄视频网站在线观看-黄视频网站免费看-黄视频网站免费观看-黄视频网站免费

千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機構(gòu)

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領(lǐng)取全套視頻
千鋒教育

關(guān)注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術(shù)干貨  > Python多核編程mpi4py實踐

Python多核編程mpi4py實踐

來源:千鋒教育
發(fā)布人:xqq
時間: 2023-11-07 08:42:21 1699317741

一、概述

CPU從三十多年前的8086,到十年前的奔騰,再到當下的多核i7。一開始,以單核cpu的主頻為目標,架構(gòu)的改良和集成電路工藝的進步使得cpu的性能高速上升,單核cpu的主頻從老爺車的MHz階段一度接近4GHz高地。然而,也因為工藝和功耗等的限制,單核cpu遇到了人生的天花板,急需轉(zhuǎn)換思維,以滿足無止境的性能需求。多核cpu在此登上歷史舞臺。給你的老爺車多加兩個引擎,讓你有法拉利的感覺。現(xiàn)時代,連手機都到處叫囂自己有4核8核處理器的時代,PC就更不用說了。

扯遠了,anyway,對于俺們程序員來說,如何利用如此強大的引擎完成我們的任務(wù)才是我們要考慮的。隨著大規(guī)模數(shù)據(jù)處理、大規(guī)模問題和復雜系統(tǒng)求解需求的增加,以前的單核編程已經(jīng)有心無力了。如果程序一跑就得幾個小時,甚至一天,想想都無法原諒自己。那如何讓自己更快的過度到高大上的多核并行編程中去呢?哈哈,廣大人民的力量!

目前工作中我所接觸到的并行處理框架主要有MPI、OpenMP和MapReduce(Hadoop)三個(CUDA屬于GPU并行編程,這里不提及)。MPI和Hadoop都可以在集群中運行,而OpenMP因為共享存儲結(jié)構(gòu)的關(guān)系,不能在集群上運行,只能單機。另外,MPI可以讓數(shù)據(jù)保留在內(nèi)存中,可以為節(jié)點間的通信和數(shù)據(jù)交互保存上下文,所以能執(zhí)行迭代算法,而Hadoop卻不具有這個特性。因此,需要迭代的機器學習算法大多使用MPI來實現(xiàn)。當然了,部分機器學習算法也是可以通過設(shè)計使用Hadoop來完成的。(淺見,如果錯誤,希望各位不吝指出,謝謝)。

本文主要介紹Python環(huán)境下MPI編程的實踐基礎(chǔ)。

二、MPI與mpi4py

MPI是MessagePassingInterface的簡稱,也就是消息傳遞。消息傳遞指的是并行執(zhí)行的各個進程具有自己獨立的堆棧和代碼段,作為互不相關(guān)的多個程序獨立執(zhí)行,進程之間的信息交互完全通過顯示地調(diào)用通信函數(shù)來完成。

Mpi4py是構(gòu)建在mpi之上的python庫,使得python的數(shù)據(jù)結(jié)構(gòu)可以在進程(或者多個cpu)之間進行傳遞。

2.1、MPI的工作方式

很簡單,就是你啟動了一組MPI進程,每個進程都是執(zhí)行同樣的代碼!然后每個進程都有一個ID,也就是rank來標記我是誰。什么意思呢?假設(shè)一個CPU是你請的一個工人,共有10個工人。你有100塊磚頭要搬,然后很公平,讓每個工人搬10塊。這時候,你把任務(wù)寫到一個任務(wù)卡里面,讓10個工人都執(zhí)行這個任務(wù)卡中的任務(wù),也就是搬磚!這個任務(wù)卡中的“搬磚”就是你寫的代碼。然后10個CPU執(zhí)行同一段代碼。需要注意的是,代碼里面的所有變量都是每個進程獨有的,雖然名字相同。

例如,一個腳本test.py,里面包含以下代碼:

frommpi4pyimportMPI

print("helloworld'')

print("myrankis:%d"%MPI.rank)

然后我們在命令行通過以下方式運行:

#mpirun–np5pythontest.py

-np5指定啟動5個mpi進程來執(zhí)行后面的程序。相當于對腳本拷貝了5份,每個進程運行一份,互不干擾。在運行的時候代碼里面唯一的不同,就是各自的rank也就是ID不一樣。所以這個代碼就會打印5個helloworld和5個不同的rank值,從0到4.

2.2、點對點通信

點對點通信(Point-to-PointCommunication)的能力是信息傳遞系統(tǒng)最基本的要求。意思就是讓兩個進程直接可以傳輸數(shù)據(jù),也就是一個發(fā)送數(shù)據(jù),另一個接收數(shù)據(jù)。接口就兩個,send和recv,來個例子:

importmpi4py.MPIasMPI

comm=MPI.COMM_WORLD

comm_rank=comm.Get_rank()

comm_size=comm.Get_size()

#pointtopointcommunication

data_send=[comm_rank]*5

comm.send(data_send,dest=(comm_rank+1)%comm_size)

data_recv=comm.recv(source=(comm_rank-1)%comm_size)

print("myrankis%d,andIreceived:"%comm_rank)

printdata_recv

啟動5個進程運行以上代碼,結(jié)果如下:

myrankis0,andIreceived:

[4,4,4,4,4]

myrankis1,andIreceived:

[0,0,0,0,0]

myrankis2,andIreceived:

[1,1,1,1,1]

myrankis3,andIreceived:

[2,2,2,2,2]

myrankis4,andIreceived:

[3,3,3,3,3]

可以看到,每個進程都創(chuàng)建了一個數(shù)組,然后把它傳遞給下一個進程,最后的那個進程傳遞給第一個進程。comm_size就是mpi的進程個數(shù),也就是-np指定的那個數(shù)。MPI.COMM_WORLD表示進程所在的通信組。

但這里面有個需要注意的問題,如果我們要發(fā)送的數(shù)據(jù)比較小的話,mpi會緩存我們的數(shù)據(jù),也就是說執(zhí)行到send這個代碼的時候,會緩存被send的數(shù)據(jù),然后繼續(xù)執(zhí)行后面的指令,而不會等待對方進程執(zhí)行recv指令接收完這個數(shù)據(jù)。但是,如果要發(fā)送的數(shù)據(jù)很大,那么進程就是掛起等待,直到接收進程執(zhí)行了recv指令接收了這個數(shù)據(jù),進程才繼續(xù)往下執(zhí)行。所以上述的代碼發(fā)送[rank]*5沒啥問題,如果發(fā)送[rank]*500程序就會半死不活的樣子了。因為所有的進程都會卡在發(fā)送這條指令,等待下一個進程發(fā)起接收的這個指令,但是進程是執(zhí)行完發(fā)送的指令才能執(zhí)行接收的指令,這就和死鎖差不多了。所以一般,我們將其修改成以下的方式:

importmpi4py.MPIasMPI

comm=MPI.COMM_WORLD

comm_rank=comm.Get_rank()

comm_size=comm.Get_size()

data_send=[comm_rank]*5

ifcomm_rank==0:

comm.send(data_send,dest=(comm_rank+1)%comm_size)

ifcomm_rank>0:

data_recv=comm.recv(source=(comm_rank-1)%comm_size)

comm.send(data_send,dest=(comm_rank+1)%comm_size)

ifcomm_rank==0:

data_recv=comm.recv(source=(comm_rank-1)%comm_size)

print("myrankis%d,andIreceived:"%comm_rank)

printdata_recv

第一個進程一開始就發(fā)送數(shù)據(jù),其他進程一開始都是在等待接收數(shù)據(jù),這時候進程1接收了進程0的數(shù)據(jù),然后發(fā)送進程1的數(shù)據(jù),進程2接收了,再發(fā)送進程2的數(shù)據(jù)……知道最后進程0接收最后一個進程的數(shù)據(jù),從而避免了上述問題。

一個比較常用的方法是封一個組長,也就是一個主進程,一般是進程0作為主進程leader。主進程將數(shù)據(jù)發(fā)送給其他的進程,其他的進程處理數(shù)據(jù),然后返回結(jié)果給進程0。換句話說,就是進程0來控制整個數(shù)據(jù)處理流程。

2.3、群體通信

點對點通信是A發(fā)送給B,一個人將自己的秘密告訴另一個人,群體通信(CollectiveCommunications)像是拿個大喇叭,一次性告訴所有的人。前者是一對一,后者是一對多。但是,群體通信是以更有效的方式工作的。它的原則就一個:盡量把所有的進程在所有的時刻都使用上!我們在下面的bcast小節(jié)講述。

群體通信還是發(fā)送和接收兩類,一個是一次性把數(shù)據(jù)發(fā)給所有人,另一個是一次性從所有人那里回收結(jié)果。

1)廣播bcast

將一份數(shù)據(jù)發(fā)送給所有的進程。例如我有200份數(shù)據(jù),有10個進程,那么每個進程都會得到這200份數(shù)據(jù)。

importmpi4py.MPIasMPI

comm=MPI.COMM_WORLD

comm_rank=comm.Get_rank()

comm_size=comm.Get_size()

ifcomm_rank==0:

data=range(comm_size)

data=comm.bcast(dataifcomm_rank==0elseNone,root=0)

print'rank%d,got:'%(comm_rank)

printdata

結(jié)果如下:

rank0,got:

[0,1,2,3,4]

rank1,got:

[0,1,2,3,4]

rank2,got:

[0,1,2,3,4]

rank3,got:

[0,1,2,3,4]

rank4,got:

[0,1,2,3,4]

Root進程自己建了一個列表,然后廣播給所有的進程。這樣所有的進程都擁有了這個列表。然后愛干嘛就干嘛了。

對廣播最直觀的觀點是某個特定進程將數(shù)據(jù)一一發(fā)送給每個進程。假設(shè)有n個進程,那么假設(shè)我們的數(shù)據(jù)在0進程,那么0進程就需要將數(shù)據(jù)發(fā)送給剩下的n-1個進程,這是非常低效的,復雜度是O(n)。那有沒有高效的方式?一個最常用也是非常高效的手段是規(guī)約樹廣播:收到廣播數(shù)據(jù)的所有進程都參與到數(shù)據(jù)廣播的過程中。首先只有一個進程有數(shù)據(jù),然后它把它發(fā)送給第一個進程,此時有兩個進程有數(shù)據(jù);然后這兩個進程都參與到下一次的廣播中,這時就會有4個進程有數(shù)據(jù),……,以此類推,每次都會有2的次方個進程有數(shù)據(jù)。通過這種規(guī)約樹的廣播方法,廣播的復雜度降為O(logn)。這就是上面說的群體通信的高效原則:充分利用所有的進程來實現(xiàn)數(shù)據(jù)的發(fā)送和接收。

2)散播scatter

將一份數(shù)據(jù)平分給所有的進程。例如我有200份數(shù)據(jù),有10個進程,那么每個進程會分別得到20份數(shù)據(jù)。

importmpi4py.MPIasMPI

comm=MPI.COMM_WORLD

comm_rank=comm.Get_rank()

comm_size=comm.Get_size()

ifcomm_rank==0:

data=range(comm_size)

printdata

else:

data=None

local_data=comm.scatter(data,root=0)

print'rank%d,got:'%comm_rank

printlocal_data

結(jié)果如下:

[0,1,2,3,4]

rank0,got:

0

rank1,got:

1

rank2,got:

2

rank3,got:

3

rank4,got:

4

這里root進程創(chuàng)建了一個list,然后將它散播給所有的進程,相當于對這個list做了劃分,每個進程獲得等分的數(shù)據(jù),這里就是list的每一個數(shù)。(主要根據(jù)list的索引來劃分,list索引為第i份的數(shù)據(jù)就發(fā)送給第i個進程)。如果是矩陣,那么就等分的劃分行,每個進程獲得相同的行數(shù)進行處理。

需要注意的是,MPI的工作方式是每個進程都會執(zhí)行所有的代碼,所以每個進程都會執(zhí)行scatter這個指令,但只有root執(zhí)行它的時候,它才兼?zhèn)浒l(fā)送者和接收者的身份(root也會得到屬于自己的數(shù)據(jù)),對于其他進程來說,他們都只是接收者而已。

3)收集gather

那有發(fā)送,就有一起回收的函數(shù)。Gather是將所有進程的數(shù)據(jù)收集回來,合并成一個列表。下面聯(lián)合scatter和gather組成一個完成的分發(fā)和收回過程:

importmpi4py.MPIasMPI

comm=MPI.COMM_WORLD

comm_rank=comm.Get_rank()

comm_size=comm.Get_size()

ifcomm_rank==0:

data=range(comm_size)

printdata

else:

data=None

local_data=comm.scatter(data,root=0)

local_data=local_data*2

print'rank%d,gotanddo:'%comm_rank

printlocal_data

combine_data=comm.gather(local_data,root=0)

ifcomm_rank==0:

printcombine_data

結(jié)果如下:

[0,1,2,3,4]

rank0,gotanddo:

0

rank1,gotanddo:

2

rank2,gotanddo:

4

rank4,gotanddo:

8

rank3,gotanddo:

6

[0,2,4,6,8]

Root進程將數(shù)據(jù)通過scatter等分發(fā)給所有的進程,等待所有的進程都處理完后(這里只是簡單的乘以2),root進程再通過gather回收他們的結(jié)果,和分發(fā)的原則一樣,組成一個list。Gather還有一個變體就是allgather,可以理解為它在gather的基礎(chǔ)上將gather的結(jié)果再bcast了一次。啥意思?意思是root進程將所有進程的結(jié)果都回收統(tǒng)計完后,再把整個統(tǒng)計結(jié)果告訴大家。這樣,不僅root可以訪問combine_data,所有的進程都可以訪問combine_data了。

4)規(guī)約reduce

規(guī)約是指不但將所有的數(shù)據(jù)收集回來,收集回來的過程中還進行了簡單的計算,例如求和,求最大值等等。為什么要有這個呢?我們不是可以直接用gather全部收集回來了,再對列表求個sum或者max就可以了嗎?這樣不是累死組長嗎?為什么不充分使用每個工人呢?規(guī)約實際上是使用規(guī)約樹來實現(xiàn)的。例如求max,完成可以讓工人兩兩pk后,再返回兩兩pk的最大值,然后再對第二層的最大值兩兩pk,直到返回一個最終的max給組長。組長就非常聰明的將工作分配下工人高效的完成了。這是O(n)的復雜度,下降到O(logn)(底數(shù)為2)的復雜度。

importmpi4py.MPIasMPI

comm=MPI.COMM_WORLD

comm_rank=comm.Get_rank()

comm_size=comm.Get_size()

ifcomm_rank==0:

data=range(comm_size)

printdata

else:

data=None

local_data=comm.scatter(data,root=0)

local_data=local_data*2

print'rank%d,gotanddo:'%comm_rank

printlocal_data

all_sum=comm.reduce(local_data,root=0,op=MPI.SUM)

ifcomm_rank==0:

print'sumis:%d'%all_sum

結(jié)果如下:

[0,1,2,3,4]

rank0,gotanddo:

0

rank1,gotanddo:

2

rank2,gotanddo:

4

rank3,gotanddo:

6

rank4,gotanddo:

8

sumis:20

可以看到,最后可以得到一個sum值。

以上內(nèi)容為大家介紹了Python多核編程mpi4py實踐,希望對大家有所幫助,如果想要了解更多Python相關(guān)知識,請關(guān)注IT培訓機構(gòu):千鋒教育。http://www.e7g2kmi.cn/

tags: python培訓
聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
10年以上業(yè)內(nèi)強師集結(jié),手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內(nèi)將與您1V1溝通
免費領(lǐng)取
今日已有369人領(lǐng)取成功
劉同學 138****2860 剛剛成功領(lǐng)取
王同學 131****2015 剛剛成功領(lǐng)取
張同學 133****4652 剛剛成功領(lǐng)取
李同學 135****8607 剛剛成功領(lǐng)取
楊同學 132****5667 剛剛成功領(lǐng)取
岳同學 134****6652 剛剛成功領(lǐng)取
梁同學 157****2950 剛剛成功領(lǐng)取
劉同學 189****1015 剛剛成功領(lǐng)取
張同學 155****4678 剛剛成功領(lǐng)取
鄒同學 139****2907 剛剛成功領(lǐng)取
董同學 138****2867 剛剛成功領(lǐng)取
周同學 136****3602 剛剛成功領(lǐng)取
相關(guān)推薦HOT
一级女性全黄生活片免费| 国产福利免费观看| 久久国产影视免费精品| 国产激情一区二区三区| 国产伦精品一区二区三区无广告| 一级女性大黄生活片免费| 亚洲第一色在线| 成人免费观看视频| 在线观看成人网 | 国产成a人片在线观看视频| 四虎久久精品国产| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 一级毛片视频免费| 日韩男人天堂| 可以免费看毛片的网站| 亚洲精品久久玖玖玖玖| 天堂网中文字幕| 麻豆系列 在线视频| 成人免费一级纶理片| 国产原创中文字幕| 成人在免费观看视频国产| 你懂的日韩| 韩国三级一区| 国产美女在线观看| 国产原创视频在线| 国产极品精频在线观看| 欧美电影免费| 午夜在线亚洲| 日本在线www| 午夜欧美成人香蕉剧场| 午夜在线影院| 国产一区精品| 91麻豆精品国产综合久久久| 日本在线播放一区| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 国产伦精品一区二区三区无广告| 国产麻豆精品视频| 91麻豆精品国产高清在线| 四虎影视久久久免费| 国产一区二区精品久久91| 亚欧乱色一区二区三区| 青青久久网| 九九精品影院| 四虎影视库| 日本特黄特黄aaaaa大片| 国产麻豆精品视频| 日韩av片免费播放| 久久国产一区二区| 毛片高清| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 一级女人毛片人一女人| 免费一级片在线| 麻豆午夜视频| 日本特黄特黄aaaaa大片| 日日夜夜婷婷| 国产原创中文字幕| 国产福利免费视频| 欧美a级片免费看| 国产视频一区在线| 九九精品影院| 国产精品1024永久免费视频| 亚洲精品中文一区不卡| 日本特黄特色aaa大片免费| 一级女人毛片人一女人| 九九精品影院| 国产麻豆精品免费密入口| 成人免费观看视频| 中文字幕一区二区三区 精品| 91麻豆tv| 欧美1区2区3区| 国产麻豆精品免费视频| 一级毛片视频免费| 国产成人精品综合| 国产不卡在线观看视频| 99色视频在线| 四虎久久影院| 夜夜操网| 亚洲精品久久久中文字| 国产一区二区精品久久91| 日韩一级黄色片| 九九精品久久| 日韩欧美一及在线播放| 日韩在线观看免费| 久久99爰这里有精品国产| 国产视频一区二区在线观看| 黄视频网站免费| 成人免费网站视频ww| 成人免费观看男女羞羞视频| 久久99中文字幕久久| 精品国产三级a| 国产精品免费精品自在线观看| 日韩专区一区| 99久久精品费精品国产一区二区| 国产视频一区在线| 国产成人精品影视| 亚洲第一色在线| 精品国产香蕉伊思人在线又爽又黄| 沈樵在线观看福利| 美女免费精品高清毛片在线视| 99色视频在线| 国产不卡高清在线观看视频 | 国产精品免费久久| 麻豆系列 在线视频| 一级女人毛片人一女人| 精品视频一区二区| 免费国产在线视频| 一级女人毛片人一女人| 免费的黄视频| 精品久久久久久中文| 韩国毛片基地| 欧美爱爱网| 天天做日日爱| 欧美一区二区三区在线观看| 久草免费在线色站| 国产91精品系列在线观看| 精品国产一级毛片| 国产精品自拍在线| 国产a毛片| 九九久久99综合一区二区| 国产91精品露脸国语对白| 四虎影视库| 国产一级强片在线观看| 亚洲精品中文字幕久久久久久| 欧美激情一区二区三区在线| 久久国产影视免费精品| 国产一区精品| 欧美日本免费| 精品久久久久久中文字幕2017| 欧美电影免费| 国产a一级| 欧美电影免费| 精品国产亚洲一区二区三区| 欧美激情一区二区三区在线播放| 成人av在线播放| 精品国产三级a| 午夜在线亚洲男人午在线| 国产91丝袜高跟系列| 国产福利免费观看| 国产麻豆精品| 一级毛片视频播放| 九九九国产| 精品久久久久久影院免费| 黄视频网站在线免费观看| 国产不卡精品一区二区三区| 精品视频一区二区三区| 国产视频网站在线观看| 国产精品免费久久| 国产视频一区在线| 99热视热频这里只有精品| 日本免费乱人伦在线观看| 九九精品影院| 一级女性全黄久久生活片| 国产精品自拍在线观看| 日韩综合| 精品视频一区二区三区| 久久久久久久男人的天堂| 精品久久久久久中文字幕一区| 国产91丝袜在线播放0| 欧美一级视频高清片| 国产美女在线一区二区三区| 亚洲精品中文字幕久久久久久| 久久久久久久久综合影视网| 成人在免费观看视频国产| 91麻豆精品国产综合久久久| 亚洲爆爽| 毛片成人永久免费视频| 欧美激情一区二区三区中文字幕| 九九九网站| 精品视频一区二区三区免费| 国产伦精品一区二区三区在线观看| 欧美国产日韩久久久| 亚洲第一色在线| 亚洲 男人 天堂| 国产a视频精品免费观看| 黄视频网站免费| 色综合久久天天综合观看| 国产原创中文字幕| 欧美电影免费看大全| 一级毛片视频播放| 在线观看成人网 | 亚洲天堂免费| 免费一级片在线| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 天天做日日爱| 成人高清视频在线观看| 欧美一级视频免费| 国产视频一区在线| 免费国产在线视频| 国产网站免费| 黄色免费三级| 国产一区二区精品久| 天天色成人网| 91麻豆精品国产片在线观看| 久草免费在线观看| 欧美a级片免费看| 欧美激情一区二区三区视频 | 天天色成人网| 日日爽天天| 精品久久久久久中文字幕2017| 国产成人精品影视|