本發(fā)明屬于計(jì)算機(jī)編譯技術(shù)領(lǐng)域,更具體地,涉及一種面向多核系統(tǒng)的數(shù)據(jù)流程序任務(wù)劃分與調(diào)度方法。
背景技術(shù):
隨著智能終端的普及,文本、圖像、音頻、視頻等流媒體使數(shù)據(jù)呈現(xiàn)爆炸式的增長(zhǎng),大數(shù)據(jù)和云計(jì)算等技術(shù)的流行對(duì)計(jì)算機(jī)的處理速度提出了更高的要求。單純地提高cpu的主頻面臨著制作難度大、功耗高等問(wèn)題,摩爾定律已經(jīng)無(wú)法適用。各大芯片廠商轉(zhuǎn)型在cpu上集成多個(gè)核心來(lái)提升處理器的性能,多核處理器具有速度快、功耗低等優(yōu)勢(shì),已經(jīng)成為現(xiàn)在處理器的主流趨勢(shì)。多核處理器在一定程度上使計(jì)算機(jī)的計(jì)算能力有了很大提高,但是多核處理器的多核優(yōu)勢(shì)還沒(méi)有充分利用。研究者們正積極尋找新的并行編程模型來(lái)挖掘多核處理器更高的性能。
典型的并行編程模型需要程序員確定程序的并行執(zhí)行順序,然后靜態(tài)地創(chuàng)建并行程序,如pthreads、mpi、openmp。當(dāng)一個(gè)靜態(tài)的并行程序執(zhí)行時(shí),許多復(fù)雜的情況可能會(huì)出現(xiàn),使程序變得繁重,例如數(shù)據(jù)競(jìng)爭(zhēng)、內(nèi)存一致性、死鎖等。如果不處理好這些復(fù)雜的情況,程序就會(huì)出現(xiàn)崩潰或得出錯(cuò)誤的結(jié)果。盡管在過(guò)去的十幾年間大量的研究已經(jīng)克服了這些模型的缺點(diǎn),但是需要編程人員對(duì)這些計(jì)算機(jī)知識(shí)非常熟悉,并且要根據(jù)底層的架構(gòu)來(lái)進(jìn)行程序的任務(wù)劃分與調(diào)度、數(shù)據(jù)通信以及同步設(shè)計(jì),這些都大大增加了程序員的工作難度和工作量。
技術(shù)實(shí)現(xiàn)要素:
針對(duì)現(xiàn)有技術(shù)的以上缺陷或改進(jìn)需求,本發(fā)明的目的在于提供了一種面向多核系統(tǒng)的數(shù)據(jù)流程序任務(wù)劃分與調(diào)度方法,由此解決現(xiàn)有技術(shù)中數(shù)據(jù)流程序執(zhí)行性能較低的技術(shù)問(wèn)題。
為實(shí)現(xiàn)上述目的,按照本發(fā)明的一個(gè)方面,提供了一種面向多核系統(tǒng)的數(shù)據(jù)流程序任務(wù)劃分與調(diào)度方法,包括以下步驟:
(1)對(duì)數(shù)據(jù)流圖中的節(jié)點(diǎn)進(jìn)行工作量統(tǒng)計(jì),選出能夠進(jìn)行分裂的目標(biāo)節(jié)點(diǎn),對(duì)無(wú)狀態(tài)的目標(biāo)節(jié)點(diǎn)進(jìn)行水平分裂,對(duì)有狀態(tài)的目標(biāo)節(jié)點(diǎn)進(jìn)行垂直分裂,其中,數(shù)據(jù)流圖由數(shù)據(jù)流程序經(jīng)數(shù)據(jù)流編譯器前端產(chǎn)生;
(2)初始化k個(gè)子圖,將經(jīng)過(guò)節(jié)點(diǎn)分裂后的數(shù)據(jù)流圖中的所有節(jié)點(diǎn)移入任一子圖vk,由子圖vk中的節(jié)點(diǎn)構(gòu)建剩余的k-1個(gè)子圖,在保證負(fù)載均衡的情況下,使得各子圖內(nèi)部的邊權(quán)之和最大來(lái)減小各子圖間的通信;
(3)采用將工作量最大的子圖中的節(jié)點(diǎn)移動(dòng)到工作量最小的子圖中,或者采用將工作量最大的子圖中的節(jié)點(diǎn)移動(dòng)到相鄰子圖中,對(duì)構(gòu)建的k個(gè)子圖進(jìn)行負(fù)載均衡優(yōu)化;
(4)對(duì)經(jīng)過(guò)負(fù)載均衡優(yōu)化后的數(shù)據(jù)流圖中的孤零節(jié)點(diǎn)移動(dòng)到與孤零節(jié)點(diǎn)的鄰接節(jié)點(diǎn)所在的子圖中,以減小子圖間的通信量,其中,孤零節(jié)點(diǎn)表示節(jié)點(diǎn)的所有鄰接節(jié)點(diǎn)都與該節(jié)點(diǎn)不在同一子圖中;
(5)將經(jīng)過(guò)通信優(yōu)化后的數(shù)據(jù)流圖中存在依賴關(guān)系的節(jié)點(diǎn)分配在不同的處理器核上,并使得存在依賴關(guān)系的節(jié)點(diǎn)在同一個(gè)流水周期內(nèi)運(yùn)行在不同的調(diào)度次數(shù)。
優(yōu)選地,所述對(duì)無(wú)狀態(tài)的目標(biāo)節(jié)點(diǎn)進(jìn)行水平分裂,對(duì)有狀態(tài)的目標(biāo)節(jié)點(diǎn)進(jìn)行垂直分裂,包括:
對(duì)無(wú)狀態(tài)的目標(biāo)節(jié)點(diǎn),若該目標(biāo)節(jié)點(diǎn)運(yùn)行次數(shù)超過(guò)第一預(yù)設(shè)值,則將該目標(biāo)節(jié)點(diǎn)水平分裂成多個(gè)相同的節(jié)點(diǎn),使得分裂后的每個(gè)節(jié)點(diǎn)處理一次任務(wù),其中,分裂后的各節(jié)點(diǎn)處于并行關(guān)系;
對(duì)于有狀態(tài)的目標(biāo)節(jié)點(diǎn),若該目標(biāo)節(jié)點(diǎn)運(yùn)行次數(shù)超過(guò)第二預(yù)設(shè)值,則將該目標(biāo)節(jié)點(diǎn)垂直分裂成多個(gè)功能相同的節(jié)點(diǎn),使得分裂后的每個(gè)節(jié)點(diǎn)處理一個(gè)任務(wù),并將分裂后的各節(jié)點(diǎn)進(jìn)行串聯(lián)。
優(yōu)選地,步驟(2)具體包括以下子步驟:
(2.1)設(shè)v1,v2,...,vk為待構(gòu)建的k個(gè)子圖,由we=wsum/k得到k個(gè)子圖的平均權(quán)值,將經(jīng)過(guò)節(jié)點(diǎn)分裂后的數(shù)據(jù)流圖中的所有節(jié)點(diǎn)移入任一子圖vk,其余子圖作為空子圖,其中,wsum表示k個(gè)子圖的總?cè)蝿?wù)量;
(2.2)對(duì)于任意空子圖vi(i≠k),從vk中隨機(jī)選擇一個(gè)節(jié)點(diǎn)加入候選集合;
(2.3)從候選集合中選擇最大增益值的節(jié)點(diǎn)v加入子圖vi,若子圖vi中的工作量小于we,則執(zhí)行步驟(2.4),否則,子圖vi構(gòu)造完成,執(zhí)行步驟(2.5);
(2.4)將與節(jié)點(diǎn)v相連的所有屬于vk的節(jié)點(diǎn)加入候選集合,并執(zhí)行步驟(2.3);
(2.5)判斷所有空子圖是否構(gòu)造完成,若存在沒(méi)有構(gòu)造完成的空子圖,則跳轉(zhuǎn)執(zhí)行步驟(2.2)。
優(yōu)選地,在步驟(3)中,采用將工作量最大的子圖中的節(jié)點(diǎn)移動(dòng)到工作量最小的子圖中,對(duì)構(gòu)建的k個(gè)子圖進(jìn)行負(fù)載均衡優(yōu)化,包括:
統(tǒng)計(jì)各子圖的工作量,獲取工作量最大的子圖與工作量最小的子圖;
遍歷工作量最大子圖中的每個(gè)節(jié)點(diǎn),若將當(dāng)前遍歷節(jié)點(diǎn)移動(dòng)到工作量最小子圖中后,工作量最大子圖的平衡因子減小,則將當(dāng)前遍歷節(jié)點(diǎn)移動(dòng)到工作量最小子圖中,其中,平衡因子表示工作量最大子圖的工作量與we相除;
對(duì)工作量最大子圖以及工作量最小子圖進(jìn)行更新,并重復(fù)執(zhí)行對(duì)工作量最大子圖中的節(jié)點(diǎn)的遍歷和移動(dòng)操作,直至遍歷完工作量最大子圖中的所有節(jié)點(diǎn)且平衡因子不再減小。
優(yōu)選地,采用將工作量最大的子圖中的節(jié)點(diǎn)移動(dòng)到相鄰子圖中,對(duì)構(gòu)建的k個(gè)子圖進(jìn)行負(fù)載均衡優(yōu)化,包括:
統(tǒng)計(jì)各子圖的工作量,獲取工作量最大的子圖;
遍歷工作量最大子圖中的每個(gè)節(jié)點(diǎn),查找與當(dāng)前遍歷節(jié)點(diǎn)的所有相鄰子圖,確定將當(dāng)前遍歷節(jié)點(diǎn)移動(dòng)到各相鄰子圖后的臨時(shí)解,對(duì)于每個(gè)臨時(shí)解,若臨時(shí)解的平衡因子與通信量均減小,則將當(dāng)前遍歷節(jié)點(diǎn)移動(dòng)到該臨時(shí)解對(duì)應(yīng)的子圖中;
對(duì)工作量最大子圖進(jìn)行更新,并重復(fù)執(zhí)行對(duì)工作量最大子圖中的節(jié)點(diǎn)的遍歷和移動(dòng)操作,直至最大子圖不變且最大子圖中的所有節(jié)點(diǎn)都已經(jīng)遍歷完成。
優(yōu)選地,所述方法還包括:
對(duì)節(jié)點(diǎn)間的緩沖區(qū)進(jìn)行改造,將單緩沖區(qū)改為雙緩沖區(qū)機(jī)制,其中,雙緩沖區(qū)機(jī)制表示對(duì)讀寫(xiě)操作交替進(jìn)行,一個(gè)緩沖區(qū)進(jìn)行讀操作時(shí),另一個(gè)緩沖區(qū)進(jìn)行寫(xiě)操作;
對(duì)雙緩沖區(qū)的內(nèi)存對(duì)齊方式按照cache行大小進(jìn)行對(duì)齊。
總體而言,通過(guò)本發(fā)明所構(gòu)思的以上技術(shù)方案與現(xiàn)有技術(shù)相比,能夠取得下列有益效果:
(1)減小了任務(wù)的粒度,提高了程序的并行性。本發(fā)明充分利用了數(shù)據(jù)流程序的軟件流水線并行、任務(wù)并行、數(shù)據(jù)并行三種并行性,對(duì)數(shù)據(jù)流圖的節(jié)點(diǎn)進(jìn)行了水平分裂和垂直分裂,為數(shù)據(jù)流程序的均衡劃分做準(zhǔn)備。
(2)任務(wù)劃分更均衡。通過(guò)初始化分、負(fù)載均衡優(yōu)化、通信邊優(yōu)化使數(shù)據(jù)流圖的任務(wù)劃分更加均衡,子圖間的通信量更小。
(3)提高了節(jié)點(diǎn)間緩沖區(qū)的效率。本發(fā)明針對(duì)節(jié)點(diǎn)間的緩沖區(qū)進(jìn)行了改造,使用雙緩沖區(qū)來(lái)避免偽共享問(wèn)題的出現(xiàn),對(duì)緩沖區(qū)按照cahce行大小進(jìn)行對(duì)齊來(lái)提高cache的命中率。
附圖說(shuō)明
圖1為本發(fā)明實(shí)施例公開(kāi)的一種面向多核系統(tǒng)的數(shù)據(jù)流程序任務(wù)劃分與調(diào)度方法的流程示意圖;
圖2為本發(fā)明實(shí)施例公開(kāi)的一種數(shù)據(jù)流程序在多核平臺(tái)上節(jié)點(diǎn)分裂算法流程圖,圖2(a)表示任務(wù)水平分裂示意圖,圖2(b)表示任務(wù)垂直分裂示意圖;
圖3為本發(fā)明實(shí)施例公開(kāi)的一種數(shù)據(jù)流程序在多核平臺(tái)上任務(wù)劃分算法流程圖,圖3(a)表示初始劃分示意圖,圖3(b)表示移動(dòng)到工作量最小子圖的負(fù)載均衡優(yōu)化,圖3(c)表示移動(dòng)到相鄰子圖的負(fù)載均衡優(yōu)化;
圖4為本發(fā)明實(shí)施例公開(kāi)的一種數(shù)據(jù)流程序在多核平臺(tái)上軟件流水線執(zhí)行示意圖,圖4(a)表示軟件流水線調(diào)度,圖4(b)表示節(jié)點(diǎn)間緩存優(yōu)化。
具體實(shí)施方式
為了使本發(fā)明的目的、技術(shù)方案及優(yōu)點(diǎn)更加清楚明白,以下結(jié)合附圖及實(shí)施例,對(duì)本發(fā)明進(jìn)行進(jìn)一步詳細(xì)說(shuō)明。應(yīng)當(dāng)理解,此處所描述的具體實(shí)施例僅僅用以解釋本發(fā)明,并不用于限定本發(fā)明。此外,下面所描述的本發(fā)明各個(gè)實(shí)施方式中所涉及到的技術(shù)特征只要彼此之間未構(gòu)成沖突就可以相互組合。
數(shù)據(jù)流編程模型使用數(shù)據(jù)流圖來(lái)進(jìn)行邏輯表達(dá),是一種高效的并行編程模型。數(shù)據(jù)流編程模型已經(jīng)被證明是最適合計(jì)算大數(shù)據(jù)的模型。數(shù)據(jù)流程序具有軟件流水線并行性、任務(wù)并行性、數(shù)據(jù)并行性,因此使用數(shù)據(jù)流程序能夠進(jìn)行高效的并行計(jì)算。多核處理器領(lǐng)域是數(shù)據(jù)流程序的主要運(yùn)行平臺(tái),數(shù)據(jù)流程序具有計(jì)算和通信分離的特點(diǎn),這點(diǎn)對(duì)多核系統(tǒng)尤為適用。如何結(jié)合數(shù)據(jù)流程序的并行性和多核系統(tǒng)的特點(diǎn),開(kāi)發(fā)數(shù)據(jù)流編程模型對(duì)數(shù)據(jù)流程序進(jìn)行任務(wù)劃分、調(diào)度、數(shù)據(jù)通信,是當(dāng)前需要解決的一大問(wèn)題。
本發(fā)明將數(shù)據(jù)流程序的任務(wù)劃分和調(diào)度與多核架構(gòu)的特點(diǎn)結(jié)合起來(lái),實(shí)現(xiàn)了對(duì)數(shù)據(jù)流程序的三級(jí)優(yōu)化過(guò)程,具體包括節(jié)點(diǎn)分裂、任務(wù)劃分、任務(wù)調(diào)度,提高了數(shù)據(jù)流程序在目標(biāo)平臺(tái)上的執(zhí)行性能。
如圖1所示為本發(fā)明實(shí)施例公開(kāi)的一種面向多核系統(tǒng)的數(shù)據(jù)流程序任務(wù)劃分與調(diào)度方法的流程示意圖,本發(fā)明采用的優(yōu)化方法以數(shù)據(jù)流編譯器前端產(chǎn)生的同步數(shù)據(jù)流圖作為輸入,對(duì)其依次進(jìn)行節(jié)點(diǎn)分裂、任務(wù)劃分、任務(wù)調(diào)度三級(jí)處理,最后生成可執(zhí)行代碼。具體步驟如下:
(1)節(jié)點(diǎn)分裂:對(duì)數(shù)據(jù)流圖中的節(jié)點(diǎn)進(jìn)行工作量統(tǒng)計(jì),選出能夠進(jìn)行分裂的目標(biāo)節(jié)點(diǎn),對(duì)無(wú)狀態(tài)的目標(biāo)節(jié)點(diǎn)進(jìn)行水平分裂,對(duì)有狀態(tài)的目標(biāo)節(jié)點(diǎn)進(jìn)行垂直分裂,其中,數(shù)據(jù)流圖由數(shù)據(jù)流程序經(jīng)數(shù)據(jù)流編譯器前端產(chǎn)生;
其中,對(duì)節(jié)點(diǎn)進(jìn)行分裂操作包括:對(duì)無(wú)狀態(tài)的目標(biāo)節(jié)點(diǎn),若該目標(biāo)節(jié)點(diǎn)運(yùn)行次數(shù)超過(guò)第一預(yù)設(shè)值,則將該目標(biāo)節(jié)點(diǎn)水平分裂成多個(gè)相同的節(jié)點(diǎn),使得分裂后的每個(gè)節(jié)點(diǎn)處理一次任務(wù),其中,分裂后的各節(jié)點(diǎn)處于并行關(guān)系;對(duì)于有狀態(tài)的目標(biāo)節(jié)點(diǎn),若該目標(biāo)節(jié)點(diǎn)運(yùn)行次數(shù)超過(guò)第二預(yù)設(shè)值,則將該目標(biāo)節(jié)點(diǎn)垂直分裂成多個(gè)功能相同的節(jié)點(diǎn),使得分裂后的每個(gè)節(jié)點(diǎn)處理一個(gè)任務(wù),并將分裂后的各節(jié)點(diǎn)進(jìn)行串聯(lián)。
具體地,對(duì)無(wú)狀態(tài)的大節(jié)點(diǎn)使用splitjoin結(jié)構(gòu)進(jìn)行水平分裂,對(duì)有狀態(tài)的大節(jié)點(diǎn)使用pipeline結(jié)構(gòu)進(jìn)行垂直分裂。使得數(shù)據(jù)流程序在多核系統(tǒng)下的任務(wù)粒度降低,并行度提高。具體步驟如下:
(1.1)水平分裂。對(duì)于無(wú)狀態(tài)的節(jié)點(diǎn),如果該計(jì)算節(jié)點(diǎn)運(yùn)行次數(shù)過(guò)多而導(dǎo)致任務(wù)量過(guò)重時(shí),可將該節(jié)點(diǎn)水平分裂成多個(gè)相同的節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)處理一次任務(wù),這樣就能減小任務(wù)的粒度。在工程實(shí)踐中,我們可以使用splitjoin結(jié)構(gòu)來(lái)實(shí)現(xiàn),如圖2(a)所示,bigoperator的運(yùn)行次數(shù)為n,我們可以按運(yùn)行次數(shù)將它分裂成n個(gè)完全相同的子節(jié)點(diǎn),每個(gè)子節(jié)點(diǎn)處理一次任務(wù)。在上游使用roundrobin(pop)形式的split節(jié)點(diǎn)來(lái)為所有子節(jié)點(diǎn)輪流分發(fā)數(shù)據(jù),每次分發(fā)pop個(gè)數(shù)據(jù),其中pop等于bigoperator的pop值。在下游使用roundrobin(push)形式的join節(jié)點(diǎn)來(lái)輪流接收所有子節(jié)點(diǎn)輸出的數(shù)據(jù),每次接收push個(gè)數(shù)據(jù),其中push等于bigoperator的push值。這樣水平分裂后,原本屬于一個(gè)節(jié)點(diǎn)的多次任務(wù),分配給了多個(gè)功能相同并且相互獨(dú)立的節(jié)點(diǎn),減小了任務(wù)的粒度,方便了后期的任務(wù)劃分操作。分裂后的節(jié)點(diǎn)是相互獨(dú)立的,因此它們之間也能達(dá)到任務(wù)的并行。
(1.2)垂直分裂。如圖2(b)所示,如果節(jié)點(diǎn)是有狀態(tài)的并且需要運(yùn)行多次時(shí),節(jié)點(diǎn)的每一次運(yùn)行都與上一次運(yùn)行有關(guān)。我們依然把節(jié)點(diǎn)分裂成多個(gè)功能相同的節(jié)點(diǎn),使得分裂后的每一個(gè)子節(jié)點(diǎn)處理一個(gè)任務(wù),然后把這些子節(jié)點(diǎn)使用pipeline結(jié)構(gòu)串聯(lián)起來(lái)??紤]到這些節(jié)點(diǎn)之間是有數(shù)據(jù)依賴的,因此我們需要對(duì)節(jié)點(diǎn)進(jìn)行改造,把具有依賴關(guān)系的變量的定義移入composite中,那么這些具有依賴關(guān)系的變量就屬于所有子節(jié)點(diǎn)共享。
(2)初始劃分:初始化k個(gè)子圖,將經(jīng)過(guò)節(jié)點(diǎn)分裂后的數(shù)據(jù)流圖中的所有節(jié)點(diǎn)移入任一子圖vk,由子圖vk中的節(jié)點(diǎn)構(gòu)建剩余的k-1個(gè)子圖,在保證負(fù)載均衡的情況下,使得各子圖內(nèi)部的邊權(quán)之和最大來(lái)減小各子圖間的通信;
其中,步驟(2)具體包括以下子步驟:
(2.1)設(shè)v1,v2,...,vk為待構(gòu)建的k個(gè)子圖,由we=wsum/k得到k個(gè)子圖的平均權(quán)值,將經(jīng)過(guò)節(jié)點(diǎn)分裂后的數(shù)據(jù)流圖中的所有節(jié)點(diǎn)移入任一子圖vk,其余子圖作為空子圖,其中,wsum表示k個(gè)子圖的總?cè)蝿?wù)量;
(2.2)對(duì)于任意空子圖vi(i≠k),從vk中隨機(jī)選擇一個(gè)節(jié)點(diǎn)加入候選集合;
(2.3)從候選集合中選擇最大增益值的節(jié)點(diǎn)v加入子圖vi,若子圖vi中的工作量小于we,則執(zhí)行步驟(2.4),否則,子圖vi構(gòu)造完成,執(zhí)行步驟(2.5);
(2.4)將與節(jié)點(diǎn)v相連的所有屬于vk的節(jié)點(diǎn)加入候選集合,并執(zhí)行步驟(2.3);
(2.5)判斷所有空子圖是否構(gòu)造完成,若存在沒(méi)有構(gòu)造完成的空子圖,則跳轉(zhuǎn)執(zhí)行步驟(2.2)。
具體地,初始劃分的實(shí)現(xiàn)方法為:如圖3(a)所示,假設(shè)v1,v2,...,vk是要構(gòu)建的k個(gè)子圖,初始劃分時(shí)先求出所有子圖的平均權(quán)值we=wsum/k,其中,wsum表示k個(gè)子圖的總?cè)蝿?wù)量,將所有的節(jié)點(diǎn)移動(dòng)至任意子圖vk,其余子圖作為空子圖。從所有節(jié)點(diǎn)中選取若干個(gè)節(jié)點(diǎn)組成候選集合,然后采用貪心的策略逐個(gè)構(gòu)建剩下的空子圖,構(gòu)造的方式是從候選集合中選擇增益函數(shù)值最大的節(jié)點(diǎn)進(jìn)行移入操作,增益函數(shù)為:
其中,v表示候選集合中的節(jié)點(diǎn),u表示空子圖vi中的節(jié)點(diǎn),u'表示子圖vk中的節(jié)點(diǎn),w(u,v)表示u、v相連的邊權(quán)值,w(u',v)表示u'、v相連的邊權(quán)值,構(gòu)造每個(gè)子圖vi的具體過(guò)程如下:初始化子圖vi為空,先隨機(jī)地從子圖vk中選擇一個(gè)節(jié)點(diǎn)加入到候選集合中,隨機(jī)的目的是保障具有多樣性的解;然后從候選集合中選擇最大增益值的節(jié)點(diǎn)v加入到子圖vi中,并且把與節(jié)點(diǎn)v相連的所有屬于vk的節(jié)點(diǎn)加入候選集合。每當(dāng)有節(jié)點(diǎn)進(jìn)入候選集合,要同步更新候選集合中節(jié)點(diǎn)的增益函數(shù)值,這樣下次移動(dòng)時(shí)便可直接讀取。子圖vi構(gòu)造完成的條件是其工作量不小于we。最后采用同樣的方法構(gòu)造剩余的空子圖。
增益函數(shù)值最大的節(jié)點(diǎn)vmax是通過(guò)以下方式獲得:首先計(jì)算各節(jié)點(diǎn)與子圖vi相連的所有邊權(quán)之和,然后計(jì)算各節(jié)點(diǎn)與vk相連的所有邊權(quán)之和,最后求出它們的差值,差值最大的節(jié)點(diǎn)即為要移動(dòng)的節(jié)點(diǎn)。
(3)負(fù)載均衡優(yōu)化:采用將工作量最大的子圖中的節(jié)點(diǎn)移動(dòng)到工作量最小的子圖中,或者采用將工作量最大的子圖中的節(jié)點(diǎn)移動(dòng)到相鄰子圖中,對(duì)構(gòu)建的k個(gè)子圖進(jìn)行負(fù)載均衡優(yōu)化;
其中,采用將工作量最大的子圖中的節(jié)點(diǎn)移動(dòng)到工作量最小的子圖中,對(duì)構(gòu)建的k個(gè)子圖進(jìn)行負(fù)載均衡優(yōu)化,包括:
統(tǒng)計(jì)各子圖的工作量,獲取工作量最大的子圖與工作量最小的子圖;
遍歷工作量最大子圖中的每個(gè)節(jié)點(diǎn),若將當(dāng)前遍歷節(jié)點(diǎn)移動(dòng)到工作量最小子圖中后,工作量最大子圖的平衡因子減小,則將當(dāng)前遍歷節(jié)點(diǎn)移動(dòng)到工作量最小子圖中,其中,平衡因子表示工作量最大子圖的工作量與we相除;
對(duì)工作量最大子圖以及工作量最小子圖進(jìn)行更新,并重復(fù)執(zhí)行對(duì)工作量最大子圖中的節(jié)點(diǎn)的遍歷和移動(dòng)操作,直至遍歷完工作量最大子圖中的所有節(jié)點(diǎn)且平衡因子不再減小。
具體地,負(fù)載均衡優(yōu)化的實(shí)現(xiàn)方法為:
如圖3(b)所示,移動(dòng)到最小子圖的負(fù)載均衡優(yōu)化算法,首先要遍歷最大子圖中的所有節(jié)點(diǎn),對(duì)于每一個(gè)節(jié)點(diǎn),嘗試移動(dòng)到最小子圖中,如果移動(dòng)后平衡因子有所減小,平衡因子指最大子圖工作量除以we,那么就進(jìn)行此次移動(dòng)。如果平衡因子沒(méi)有減小,則撤銷(xiāo)此次移動(dòng)。移動(dòng)后最大子圖的負(fù)載和最小子圖的負(fù)載都會(huì)發(fā)生變化,最大子圖減小的負(fù)載等于移動(dòng)節(jié)點(diǎn)的工作量,最小子圖增加的負(fù)載也等于移動(dòng)節(jié)點(diǎn)的工作量。移動(dòng)成功后,要重新選擇新的最大子圖和最小子圖,然后采取同樣的移動(dòng)操作,直到遍歷完最大子圖中的所有節(jié)點(diǎn)且平衡因子不再減小,新的最大子圖中的所有節(jié)點(diǎn)的移動(dòng)都被撤銷(xiāo)就終止此優(yōu)化算法。
如圖3(c)所示,移動(dòng)到相鄰子圖的負(fù)載均衡優(yōu)化算法,也是要先遍歷最大子圖中的所有節(jié)點(diǎn),對(duì)于每一個(gè)節(jié)點(diǎn),嘗試移動(dòng)到與之相鄰的子圖中,如果存在多個(gè)相鄰子圖,則分別移動(dòng)多次,得出多個(gè)臨時(shí)解。對(duì)于每一個(gè)臨時(shí)解,如果此臨時(shí)解的平衡因子減小了并且通信量也減小了,就將當(dāng)前的劃分替換為臨時(shí)解。然后從多個(gè)臨時(shí)解出發(fā)繼續(xù)進(jìn)行移動(dòng)操作,已經(jīng)移動(dòng)過(guò)的節(jié)點(diǎn)不會(huì)再移回原來(lái)的子圖。如果移動(dòng)后平衡因子沒(méi)有減小則就撤銷(xiāo)此次移動(dòng)。同樣,移動(dòng)后的最大子圖也可能會(huì)發(fā)生變化,因此下一輪要更換最大子圖。直到最大子圖不變并且最大子圖中的所有節(jié)點(diǎn)都已經(jīng)遍歷完成。
(4)子圖間通信邊優(yōu)化:對(duì)經(jīng)過(guò)負(fù)載均衡優(yōu)化后的數(shù)據(jù)流圖中的孤零節(jié)點(diǎn)移動(dòng)到與孤零節(jié)點(diǎn)的鄰接節(jié)點(diǎn)所在的子圖中,以減小子圖間的通信量,其中,孤零節(jié)點(diǎn)表示節(jié)點(diǎn)的所有鄰接節(jié)點(diǎn)都與該節(jié)點(diǎn)不在同一子圖中;
其中,采用將工作量最大的子圖中的節(jié)點(diǎn)移動(dòng)到相鄰子圖中,對(duì)構(gòu)建的k個(gè)子圖進(jìn)行負(fù)載均衡優(yōu)化,包括:
統(tǒng)計(jì)各子圖的工作量,獲取工作量最大的子圖;
遍歷工作量最大子圖中的每個(gè)節(jié)點(diǎn),查找與當(dāng)前遍歷節(jié)點(diǎn)的所有相鄰子圖,確定將當(dāng)前遍歷節(jié)點(diǎn)移動(dòng)到各相鄰子圖后的臨時(shí)解,對(duì)于每個(gè)臨時(shí)解,若臨時(shí)解的平衡因子與通信量均減小,則將當(dāng)前遍歷節(jié)點(diǎn)移動(dòng)到該臨時(shí)解對(duì)應(yīng)的子圖中;
對(duì)工作量最大子圖進(jìn)行更新,并重復(fù)執(zhí)行對(duì)工作量最大子圖中的節(jié)點(diǎn)的遍歷和移動(dòng)操作,直至最大子圖不變且最大子圖中的所有節(jié)點(diǎn)都已經(jīng)遍歷完成。
具體地,子圖間通信邊優(yōu)化的實(shí)現(xiàn)方法為:
在數(shù)據(jù)流圖中,子圖間的通信量是指相鄰子圖間邊的權(quán)值大小??梢愿鶕?jù)一個(gè)節(jié)點(diǎn)的所有鄰接節(jié)點(diǎn)所處的位置將節(jié)點(diǎn)分為三種:
1、內(nèi)部節(jié)點(diǎn):如果一個(gè)節(jié)點(diǎn)的所有鄰接節(jié)點(diǎn)都和和它在同一子圖中,則稱該節(jié)點(diǎn)為內(nèi)部節(jié)點(diǎn),內(nèi)部節(jié)點(diǎn)是需要保護(hù)的節(jié)點(diǎn),禁止移動(dòng)。
2、邊界節(jié)點(diǎn):如果一個(gè)節(jié)點(diǎn)的所有鄰接節(jié)點(diǎn)有一部分與它在同一子圖中,另一部分在其它子圖中,則稱該節(jié)點(diǎn)為邊界節(jié)點(diǎn),邊界節(jié)點(diǎn)是可以考慮移動(dòng)的節(jié)點(diǎn)。
3、孤零節(jié)點(diǎn):如果一個(gè)節(jié)點(diǎn)的所有鄰接節(jié)點(diǎn)都與它不在同一子圖中,則稱該節(jié)點(diǎn)為孤零節(jié)點(diǎn),孤零節(jié)點(diǎn)是首要考慮移動(dòng)的節(jié)點(diǎn)。
對(duì)于孤零節(jié)點(diǎn),提出了孤零節(jié)點(diǎn)的歸并策略。在不影響負(fù)載均衡的前提下,將孤零節(jié)點(diǎn)移到鄰接節(jié)點(diǎn)所在的子圖中,可有效減小子圖間的通信量。如果存在多個(gè)鄰接節(jié)點(diǎn)的子圖,則要嘗試多次移動(dòng),然后選取使通信量最小的移動(dòng)。
(5)將經(jīng)過(guò)通信優(yōu)化后的數(shù)據(jù)流圖中存在依賴關(guān)系的節(jié)點(diǎn)分配在不同的處理器核上,并使得存在依賴關(guān)系的節(jié)點(diǎn)在同一個(gè)流水周期內(nèi)運(yùn)行在不同的調(diào)度次數(shù)。
在另一個(gè)實(shí)施例中,針對(duì)任務(wù)劃分結(jié)果進(jìn)行軟件流水線調(diào)度和緩存優(yōu)化。多核環(huán)境下的軟件流水線模型主要是處理器的多個(gè)核心、計(jì)算節(jié)點(diǎn)、計(jì)算節(jié)點(diǎn)間的緩沖區(qū)相互協(xié)同作業(yè)的過(guò)程。為了使軟件流水線發(fā)揮最大的性能,各級(jí)流水線之間的負(fù)載均衡是關(guān)鍵因素。負(fù)載均衡在數(shù)據(jù)流程序的任務(wù)劃分時(shí)已經(jīng)得到了保證,因此在調(diào)度時(shí)主要針對(duì)節(jié)點(diǎn)的調(diào)度順序和節(jié)點(diǎn)間的緩沖區(qū)。具體步驟如下:
(a)軟件流水線調(diào)度
對(duì)劃分后的節(jié)點(diǎn)進(jìn)行階段賦值,得到其執(zhí)行的先后順序。
根據(jù)劃分后的結(jié)果把任務(wù)子圖分配到相應(yīng)的處理器核上,調(diào)度時(shí)分為3個(gè)階段:填充階段、穩(wěn)態(tài)階段、排空階段。填充階段為程序運(yùn)行的開(kāi)始階段,為穩(wěn)態(tài)階段逐漸積累數(shù)據(jù),只有部分節(jié)點(diǎn)運(yùn)行。當(dāng)數(shù)據(jù)積累到穩(wěn)態(tài)階段所能執(zhí)行的限度時(shí),便會(huì)進(jìn)入穩(wěn)態(tài)階段。進(jìn)入穩(wěn)態(tài)執(zhí)行階段后,相同流水周期內(nèi)各計(jì)算任務(wù)無(wú)任何數(shù)據(jù)依賴,可以達(dá)到完全的并行,因?yàn)樗鼈冞\(yùn)行所需的數(shù)據(jù)已經(jīng)在上一流水周期放入了緩沖區(qū)。排空階段是程序運(yùn)行的結(jié)束階段,計(jì)算節(jié)點(diǎn)會(huì)依次停止運(yùn)行。
圖4(a)左邊是一個(gè)簡(jiǎn)單的數(shù)據(jù)流圖,每個(gè)下游節(jié)點(diǎn)都會(huì)依賴上游節(jié)點(diǎn)產(chǎn)生的數(shù)據(jù),因此如果在同一個(gè)流水周期內(nèi),這些節(jié)點(diǎn)不可能運(yùn)行在同一調(diào)度次數(shù)。為了使這些節(jié)點(diǎn)能夠并行,在空間上把它們進(jìn)行隔離,使它們位于不同的處理器核上。在時(shí)間把它們進(jìn)行錯(cuò)開(kāi),使在同一個(gè)流水周期內(nèi)它們運(yùn)行在不同的調(diào)度次數(shù)。
圖4(a)右邊給出了節(jié)點(diǎn)的調(diào)度圖,在第一個(gè)流水周期,a節(jié)點(diǎn)開(kāi)始運(yùn)行,a節(jié)點(diǎn)運(yùn)行完成之后會(huì)把產(chǎn)生的結(jié)果放在a與b的緩沖區(qū)中。緩沖區(qū)通過(guò)dma(directmemoryaccess)把數(shù)據(jù)傳給計(jì)算節(jié)點(diǎn)b。到第二個(gè)流水周期的時(shí)候,a節(jié)點(diǎn)繼續(xù)進(jìn)行下一次的調(diào)度,由于b節(jié)點(diǎn)運(yùn)行所需要的數(shù)據(jù)已經(jīng)在上一個(gè)周期中由a節(jié)點(diǎn)放入緩沖區(qū),因此在a節(jié)點(diǎn)運(yùn)行的同時(shí)b節(jié)點(diǎn)也會(huì)運(yùn)行。同樣,在a運(yùn)行完成后會(huì)把新的數(shù)據(jù)覆蓋在原來(lái)a與b的緩沖區(qū)中,同時(shí)b產(chǎn)生的數(shù)據(jù)寫(xiě)入b與c之間的緩沖區(qū)。到第三個(gè)流水周期的時(shí)候,c節(jié)點(diǎn)會(huì)讀取b節(jié)點(diǎn)在第二個(gè)周期寫(xiě)入的數(shù)據(jù),然后開(kāi)始運(yùn)行,這樣從第三個(gè)流水周期開(kāi)始三個(gè)節(jié)點(diǎn)都能在核上運(yùn)行,達(dá)到了軟件流水線并行。由于程序的調(diào)度次數(shù)是6次,因此一直到第六個(gè)流水周期三個(gè)節(jié)點(diǎn)都在運(yùn)行。從第七個(gè)流水周期開(kāi)始a節(jié)點(diǎn)執(zhí)行結(jié)束,那么a節(jié)點(diǎn)和b節(jié)點(diǎn)的緩沖區(qū)中便不會(huì)有數(shù)據(jù),但是此時(shí)b節(jié)點(diǎn)和c節(jié)點(diǎn)還是會(huì)運(yùn)行,因?yàn)樗鼈兪褂玫纳弦粋€(gè)周期產(chǎn)生的數(shù)據(jù)。到第八個(gè)流水周期后,b節(jié)點(diǎn)發(fā)現(xiàn)上游緩沖區(qū)中無(wú)數(shù)據(jù),因此也結(jié)束運(yùn)行,此時(shí)只有c節(jié)點(diǎn)運(yùn)行。第八個(gè)流水周期之后c節(jié)點(diǎn)也會(huì)停止運(yùn)行。
(b)緩沖區(qū)優(yōu)化
目前數(shù)據(jù)流編程模型的緩沖區(qū)采用的是共享內(nèi)存的單緩沖區(qū)機(jī)制,緩沖區(qū)的長(zhǎng)度是固定的。在軟件流水線調(diào)度的過(guò)程中,為了保證數(shù)據(jù)的一致性,上游節(jié)點(diǎn)會(huì)和下游節(jié)點(diǎn)同時(shí)對(duì)緩沖區(qū)進(jìn)行寫(xiě)和讀,區(qū)別在于上游節(jié)點(diǎn)是對(duì)當(dāng)前周期的數(shù)據(jù)進(jìn)行操作,而下游節(jié)點(diǎn)是對(duì)上游節(jié)點(diǎn)在前一個(gè)周期產(chǎn)生的數(shù)據(jù)進(jìn)行操作。當(dāng)上游節(jié)點(diǎn)和下游節(jié)點(diǎn)位于不同的處理器核上時(shí),它們之間通過(guò)共享內(nèi)存的方式通信。如果上游節(jié)點(diǎn)和下游節(jié)點(diǎn)對(duì)緩沖區(qū)的同一cache行進(jìn)行頻繁地讀寫(xiě),就會(huì)出現(xiàn)偽共享問(wèn)題。偽共享問(wèn)題的出現(xiàn)會(huì)大大增加線程對(duì)內(nèi)存的讀寫(xiě)時(shí)間,影響程序的執(zhí)行效率。
針對(duì)偽共享問(wèn)題的出現(xiàn),首先對(duì)緩沖區(qū)進(jìn)行改造,使用雙緩沖區(qū)機(jī)制。雙緩沖區(qū)機(jī)制的出現(xiàn)可以避免上游節(jié)點(diǎn)和下游節(jié)點(diǎn)對(duì)同一個(gè)緩沖區(qū)進(jìn)行讀寫(xiě),如圖4(b)所示,a節(jié)點(diǎn)是上游節(jié)點(diǎn),當(dāng)a節(jié)點(diǎn)寫(xiě)數(shù)據(jù)時(shí)是對(duì)buffer1進(jìn)行寫(xiě),當(dāng)a節(jié)點(diǎn)寫(xiě)入完一次數(shù)據(jù)后指針指向buffer2的緩沖區(qū),開(kāi)始對(duì)buffer2進(jìn)行寫(xiě)。b節(jié)點(diǎn)是下游節(jié)點(diǎn),當(dāng)a節(jié)點(diǎn)對(duì)buffer1進(jìn)行寫(xiě)的時(shí)候,b節(jié)點(diǎn)的指針指向buffer2,如果buffer2中有數(shù)據(jù)b節(jié)點(diǎn)就會(huì)從中讀取,如果buffer2中沒(méi)有數(shù)據(jù)buffer2就會(huì)進(jìn)入同步等待狀態(tài)。當(dāng)a節(jié)點(diǎn)對(duì)buffer1寫(xiě)入完成并指向buffer2后,b節(jié)點(diǎn)的指針同時(shí)也會(huì)發(fā)生變化指向buffer1,由于buffer1已由a節(jié)點(diǎn)寫(xiě)入了數(shù)據(jù),因此a節(jié)點(diǎn)對(duì)buffer2寫(xiě)入數(shù)據(jù)的同時(shí)b節(jié)點(diǎn)會(huì)從buffer1中讀取數(shù)據(jù)。這樣就能保證a節(jié)點(diǎn)和b節(jié)點(diǎn)對(duì)數(shù)據(jù)的操作是位于不同的緩沖區(qū)的。
其次對(duì)雙緩沖區(qū)的內(nèi)存對(duì)齊方式按照cache行的大小進(jìn)行對(duì)齊。按照cache行的大小進(jìn)行對(duì)齊的好處是能夠增加cache的命中率。由于多核處理器對(duì)cache的讀寫(xiě)速度明顯快于內(nèi)存,如果計(jì)算節(jié)點(diǎn)對(duì)數(shù)據(jù)的讀寫(xiě)能夠直接來(lái)自于緩沖區(qū),那么這將大大加快計(jì)算節(jié)點(diǎn)間的通信速度。
本領(lǐng)域的技術(shù)人員容易理解,以上所述僅為本發(fā)明的較佳實(shí)施例而已,并不用以限制本發(fā)明,凡在本發(fā)明的精神和原則之內(nèi)所作的任何修改、等同替換和改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。