專利名稱::單線程代碼到推測預(yù)執(zhí)行啟用代碼的變換的制作方法
技術(shù)領(lǐng)域:
:本發(fā)明涉及計算系統(tǒng)軟件,尤其是線程管理。
背景技術(shù):
:對現(xiàn)代計算系統(tǒng)的有效操作通常需要多指令“線程”支持,每個線程是在一程序中提供清楚的控制流的指令流。為提高整體系統(tǒng)速度和響應(yīng),多線程可通過具有多處理器的計算系統(tǒng)同時實(shí)現(xiàn),其中每個處理器支持一單線程。在更先進(jìn)的計算系統(tǒng)中,可利用具有能同時執(zhí)行多線程的多線程處理器結(jié)構(gòu)的處理器來支持多線程??商鎿Q的方案是,在通常被稱為時間片多線程的技術(shù)中,在一固定時間段之后可在線程之間復(fù)用一單個處理器。在另一被稱為事件切換多線程的方法中,依據(jù)諸如一長等候高速緩存未中的觸發(fā)器事件的發(fā)生,一單個處理器在線程之間切換。多線程的概念已發(fā)展到被稱作同步多線程(“SMT”)的技術(shù)。同步多線程是將硬件多線程與超標(biāo)量處理器技術(shù)結(jié)合起來的處理器設(shè)計,從而允許多線程每周期發(fā)布指令。SMT典型地允許所有線程內(nèi)容同時競爭并共享處理器資源。在一些實(shí)現(xiàn)中,一單個物理處理器可作為操作系統(tǒng)和用戶程序的多邏輯處理器,其中每個邏輯處理器保持一整組結(jié)構(gòu)狀態(tài),但物理處理器的幾乎所有其它資源,例如高速緩存、執(zhí)行單元、分支預(yù)測器、控制邏輯和總線,均被共享。線程同時執(zhí)行并且比時間片多線程或事件切換多線程更好地利用共享資源。此多線程支持處理器的有效應(yīng)用需要用于自動優(yōu)化程序行為的過程和最好的優(yōu)化候選者的代碼標(biāo)識部分。通過將一原始單線程應(yīng)用變換為一實(shí)際多線程代碼,采用一組線程機(jī)制標(biāo)識的代碼優(yōu)化區(qū)域增強(qiáng)了程序性能。在一現(xiàn)有技術(shù)中,創(chuàng)建一“推測預(yù)執(zhí)行”(SP)線程,從而與作為一主線程的原始代碼并行運(yùn)行。此SP線程將在主線程之前運(yùn)行并遇到未來高速緩存未中,因此執(zhí)行用于主線程的有效預(yù)取。然而,由于線程同步發(fā)布,此技術(shù)不總是有效。
發(fā)明內(nèi)容本發(fā)明第一方面提供一代碼轉(zhuǎn)換方法,包括在一主程序中標(biāo)識一組可被動態(tài)激活作為推測預(yù)執(zhí)行線程的指令,并通過一組全局變量指示非推測線程進(jìn)度,允許此推測預(yù)執(zhí)行線程規(guī)范相對于非推測線程的相對進(jìn)度。本發(fā)明第二方面提供一種包括具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,所述指令被執(zhí)行時將導(dǎo)致在一主程序中標(biāo)識一組可被動態(tài)激活作為推測預(yù)執(zhí)行線程的指令,并通過一組全局變量指示非推測線程進(jìn)度,允許此推測預(yù)執(zhí)行線程規(guī)范相對于非推測線程的相關(guān)進(jìn)度。本發(fā)明第三方面提供一種計算系統(tǒng),包括一優(yōu)化模塊,用來在一主程序中標(biāo)識一組可被動態(tài)激活作為推測預(yù)執(zhí)行線程的指令;以及一同步模塊,包括存儲全局變量的存儲器,此同步模塊通過一組全局變量指示非推測線程的進(jìn)度,允許此推測預(yù)執(zhí)行線程規(guī)范相對于非推測線程的相關(guān)進(jìn)度。通過以下詳細(xì)描述和本發(fā)明實(shí)施例的附圖,本發(fā)明將更被充分理解,然而以下詳細(xì)描述和本發(fā)明實(shí)施例的附圖不是將本發(fā)明局限于特定實(shí)施例,而僅用于解釋和理解。圖1示意性地表示支持多線程處理的一計算系統(tǒng);圖2示意性地表示在推測預(yù)執(zhí)行期間的一存儲器訪問模式;而且圖3示意性地表示用作推測預(yù)執(zhí)行的程序邏輯,該推測預(yù)執(zhí)行包括對用于線程同步的全局變量的存儲器訪問。具體實(shí)施例方式圖1表示一計算系統(tǒng)10,用于執(zhí)行作為計算機(jī)程序產(chǎn)品的軟件外部提供并存儲在數(shù)據(jù)儲存單元的指令,計算系統(tǒng)10包括一或多個處理器12和存儲系統(tǒng)13(此存儲系統(tǒng)可為外部高速緩沖存儲器,外部RAM,和/或部分在處理器內(nèi)部的存儲器)。處理器12表示一或多個用于執(zhí)行軟件線程并能支持多線程的處理單元。處理器12可包括但不局限于傳統(tǒng)多路復(fù)用處理器、共享一些普通存儲器的多處理器、在一單個芯片上具有多指令設(shè)置處理單元的芯片多處理器“CMP”、對稱多處理器“SMP”或同步多線程處理器“SMT處理器”。本發(fā)明的計算機(jī)系統(tǒng)10可包括一或多個I/O(輸入/輸出)設(shè)備15,包括諸如監(jiān)控器的一顯示設(shè)備。此I/O設(shè)備也可包括一輸入設(shè)備,例如一鍵盤和諸如鼠標(biāo)、跟蹤球或軌跡板的一光標(biāo)控制。而且,I/O設(shè)備也可包括一網(wǎng)絡(luò)連接器以便計算機(jī)系統(tǒng)10是局域網(wǎng)(LAN)或廣域網(wǎng)(WAN)的一部分。例如,一系統(tǒng)10包括但不局限于或限制于一計算機(jī)(例如,一臺式機(jī)、一便攜機(jī)、一服務(wù)器、刀片式服務(wù)器、一工作站、一個人數(shù)字助理等)或任何與之關(guān)聯(lián)的外部設(shè)備;通信裝備(例如手提電話、傳呼機(jī)等);一電視機(jī)機(jī)頂盒等?!斑B接”或“鏈接”被廣泛定義為邏輯或物理通信路徑,例如電線、光纖、電纜、總線跟蹤或者甚至是利用紅外、射頻(RF)或任何其他無線信號機(jī)制的無線通道。而且,術(shù)語“信息”被定義為一或多個比特數(shù)據(jù)、地址和/或控制?!按a”包括運(yùn)行時執(zhí)行一定功能的軟件或固件。例如,代碼包括一應(yīng)用、操作系統(tǒng)、一小程序、引導(dǎo)代碼或任何其他指令序列或微代碼(即,在特權(quán)級別且在OS下操作的代碼)。可選地,執(zhí)行如上所述的方法和系統(tǒng)的邏輯可在附加計算機(jī)和/或機(jī)器可讀介質(zhì)上實(shí)現(xiàn),諸如作為大規(guī)模集成電路(LSI)的分離硬件組件、專用集成電路(ASIC)、微代碼或諸如電可擦除可編程只讀存儲器(EEPROM)的固件;或通過電、光、聲以及其他形式的傳播信號的空間距離計算機(jī)延遲信息(例如,無線電波或紅外光學(xué)信號)。在一實(shí)施例中,依據(jù)本發(fā)明,由數(shù)據(jù)儲存單元18可讀的一計算機(jī)程序產(chǎn)品包括一機(jī)器或計算機(jī)可讀介質(zhì),該計算機(jī)可讀介質(zhì)具有存儲其上的指令,該指令可用于編程(即定義其操作)一計算機(jī)(或其他電子設(shè)備)來執(zhí)行一處理的程序。數(shù)據(jù)儲存單元18的計算機(jī)可讀介質(zhì)可包括但不局限于軟盤、光盤、高密度磁盤、只讀存儲器(CD-ROM)和磁-光盤、只讀存儲器(ROM)、隨機(jī)存取存儲器(RAM)、可擦除可編程只讀存儲器(EEPROM)、電可擦除可編程只讀存儲器(EEPROM)、磁或光卡、閃存等,包括升級或重編程或產(chǎn)生或激活或保留激活微代碼增強(qiáng)的任何方法。因此,計算機(jī)可讀介質(zhì)包括任何種適合存儲電子指令的介質(zhì)/機(jī)器可讀介質(zhì)。而且,本發(fā)明也可作為一計算機(jī)程序產(chǎn)品下載。因此,可將此程序從一遠(yuǎn)程計算機(jī)(例如,一服務(wù)器)傳輸?shù)揭徽埱笥嬎銠C(jī)(例如,一客戶機(jī))??衫幂d波或其他傳播介質(zhì)中內(nèi)嵌的數(shù)據(jù)信號經(jīng)由通信鏈接(例如,一調(diào)制解調(diào)器、網(wǎng)絡(luò)連接等)來傳輸所述程序。在一實(shí)施例中,本發(fā)明的方法被嵌入到機(jī)器可執(zhí)行指令,此指令直接控制計算系統(tǒng)10的操作,而且更具體地是控制處理器、寄存器、高速緩沖存儲器和通用存儲器的操作。該指令可用于使得采用該指令編程的通用目的或特定目的處理器執(zhí)行本發(fā)明的步驟??蛇x地,可通過包含用于執(zhí)行此步驟的硬線邏輯的特定硬件組件(包括微代碼)或者通過編程計算機(jī)組件和客戶硬件組件的任意組合執(zhí)行本發(fā)明的步驟。本領(lǐng)域普通技術(shù)人員可以理解用來描述通信、協(xié)議、應(yīng)用、實(shí)現(xiàn)、機(jī)制等所使用的各術(shù)語和技術(shù)。此技術(shù)是對依據(jù)算法或數(shù)學(xué)表達(dá)式的技術(shù)實(shí)現(xiàn)的描述。也就是,例如,當(dāng)此技術(shù)作為計算機(jī)上的執(zhí)行代碼來實(shí)現(xiàn)時,此技術(shù)的表達(dá)式作為偽代碼可更適當(dāng)和簡明地傳送和通信,此偽代碼通常通過公式、算法或數(shù)學(xué)表達(dá)式來定義程序流邏輯。因此,本領(lǐng)域普通技術(shù)人員將認(rèn)識表示A+B=C的塊,它是作為加法功能,其在硬件和/或軟件中是通過獲得兩個輸入(A和B)并產(chǎn)生一和輸出(C)來實(shí)現(xiàn)的。因此,描述中公式、算法或數(shù)學(xué)表達(dá)式的作用是至少在硬件和/或軟件上具有一物理實(shí)施例(例如,本發(fā)明的技術(shù)可作為一實(shí)施例在其中實(shí)踐或?qū)崿F(xiàn)的一計算機(jī)系統(tǒng))。圖2中20表示在一計算系統(tǒng)中的線程運(yùn)行,此計算系統(tǒng)支持能將單線程應(yīng)用變換為推測預(yù)執(zhí)行(SP)增強(qiáng)多線程代碼的一編譯器或傳遞后優(yōu)化層,該增強(qiáng)多線程代碼使用操作系統(tǒng)線程所明顯支持的線程(例如WIN32線程API)、對OS透明的用戶層線程或經(jīng)由微代碼等的硬件線程支持。應(yīng)該注意的是,支持SP代碼轉(zhuǎn)換可用于實(shí)際上將任何可包括錯誤預(yù)測的間接分支的長等候操作作為目標(biāo)。例如,在一實(shí)施例中,轉(zhuǎn)換到SP代碼典型地需要標(biāo)識一小組“非法加載”,也就是在發(fā)生最多高速緩存未中的程序中的加載指令。標(biāo)識此組導(dǎo)致用于這些非法加載的地址計算的指令,并從可被動態(tài)激活的主線程將用于這些非法加載的指令創(chuàng)建為一分離SP線程。實(shí)際上,由于在主線程運(yùn)行期間SP線程不用時進(jìn)入休眠,可在初始化時創(chuàng)建SP線程,在運(yùn)行期間產(chǎn)生最小處理器開銷。然而,SP線程,如果在初始化之后被一合適的同步或異步觸發(fā)器喚醒并在主線程之前執(zhí)行到早計算地址和執(zhí)行存儲器訪問,仍可導(dǎo)致用于非法加載的有效存儲器預(yù)取。通過在主線程(不將產(chǎn)生未中)訪問之前確保在SP線程發(fā)生高速緩存未中,SP線程的早期存儲器預(yù)取可大大提高主線程性能。如圖3所示,SP線程創(chuàng)建和運(yùn)行的處理30從一優(yōu)化模塊32開始,此模塊用于在一主程序中標(biāo)識一組可作為推測預(yù)執(zhí)行線程被動態(tài)派生的指令??稍诔绦虺跏蓟瘯r動態(tài)標(biāo)識或通過編譯器脫機(jī)進(jìn)行標(biāo)識。在任一情況下(動態(tài)運(yùn)行時間創(chuàng)建或脫機(jī)編譯器標(biāo)識),在程序初始化期間此SP線程被動態(tài)創(chuàng)建為一運(yùn)行時間實(shí)體。由于線程創(chuàng)建典型地為大計算量過程,此一次SP線程創(chuàng)建是有用的。只要需要一線程那么就創(chuàng)建一新SP線程,將否定通過利用推測預(yù)執(zhí)行所獲得的加速。只在開始所有應(yīng)用時創(chuàng)建SP線程來分期償還線程創(chuàng)建的整體花銷。一延遲軟件模塊34用于在線程創(chuàng)建和激活之間對推測預(yù)執(zhí)行線程執(zhí)行一個等待/休眠操作。SP線程與其相應(yīng)非推測線程的相應(yīng)部分運(yùn)行頻率相同。在大多數(shù)應(yīng)用中,在SP線程創(chuàng)建和SP線程激活之間存在一些離散時間,在連續(xù)SP線程激活之間也存在一些離散時間。在這些時間期間,SP線程執(zhí)行一等待/休眠操作從而允許SP線程轉(zhuǎn)入系統(tǒng)希望在邏輯處理器上運(yùn)行的其他處理。一同步模塊36(包括存儲全局變量的存儲器訪問功能性)通過一組全局變量跟蹤非推測線程的進(jìn)度,允許推測預(yù)執(zhí)行(SP)線程指示相對于非推測線程的進(jìn)度。所給SP和非SP線程可讀并寫入一組共享變量,此組共享變量有助于約束所有對此組帶有一快速、同步對象的全局變量的訪問。此同步對象可直接來自O(shè)S線程API,例如在Win32線程API或p線程的等價API中通過setEvent()和waitForSingleObject()來操作的事件對象??蛇x地,此同步對象可經(jīng)由合適的硬件線程等待監(jiān)控器實(shí)現(xiàn),此監(jiān)控器允許一線程將一與存儲器地址對準(zhǔn)的緩存線定義為監(jiān)控器,而且對此監(jiān)控器對象的加載訪問可掛起所述線程運(yùn)行——使之語義地與WaitForSingleObject()等價;而且訪問監(jiān)控器的存儲器可喚醒掛起線程——因此與setEvent()等價。然而,值得注意的是,雖然監(jiān)控器寫和m等待比一OS水平線程API有效得多,所述實(shí)施例可采用任何支持等待和喚醒的軟件、硬件或軟件硬件混合機(jī)制實(shí)現(xiàn)。除了采用全局變量并提供一等待狀態(tài),用于SP優(yōu)化操作的代碼變換還可包括限制SP線程和非推測主線程之間的通信頻率。定義“stride”為一變量,等于一SP線程相對于一非推測主線程之前運(yùn)行的循環(huán)迭代數(shù),這些線程可被設(shè)置為只在stride操作之后訪問此組共享全局變量。這最小化了通信,線程提前運(yùn)行和推后完成也局限于stride單位的大小。在某些實(shí)施例中,SP線程經(jīng)常在非推測線程之前運(yùn)行,而且任何同步通信均為不必要的開銷,不使用依賴stride的通信限制。如所期望地,stride選擇經(jīng)常影響應(yīng)用性能。如果stride設(shè)置太低(提前運(yùn)行距離太短,所需線程間通信更頻繁,而且SP線程的非時存儲器訪問更頻繁),則通信開銷開始否定SP線程的好處。另一方面,假如設(shè)置得太高,SP線程太提前運(yùn)行而且一些以前的預(yù)取數(shù)據(jù)在主線程使用之前被覆蓋,則為不充分線程通信,而且可產(chǎn)生錯誤或不必要(即非時)預(yù)取。在多數(shù)應(yīng)用中,SP線程在非推測線程之后完成和/或之前運(yùn)行。通過動態(tài)增加或減少推測線程運(yùn)行,經(jīng)由線程之間優(yōu)質(zhì)通信,推后完成和/或提前運(yùn)行頻率可最小。假如SP線程發(fā)現(xiàn)其在非推測線程之后,它可通過試圖跳轉(zhuǎn)到上一次通信位置之前來有效增加它的執(zhí)行。另一方面,假如SP線程發(fā)現(xiàn)其在非推測線程之前運(yùn)行,它可使用兩個技術(shù)之一來減少執(zhí)行等待和跳回。采用等待技術(shù),SP線程簡單產(chǎn)生并等待非推測線程發(fā)信號??蛇x地,一跳回技術(shù)可用于SP線程運(yùn)行需要跳回到非推測線程的最后已知位置并開始再次預(yù)取的情況。一SP線程也可在其非推測線程之后完成。這樣的話,非推測線程已經(jīng)完成了SP預(yù)取的代碼部分,當(dāng)SP線程繼續(xù)執(zhí)行時此應(yīng)用產(chǎn)生附加的不必要的高速緩存未中。在一個實(shí)施例中,SP線程在每個提前執(zhí)行操作跨距的終點(diǎn)包括一調(diào)節(jié)機(jī)制,用來檢查主線程的相關(guān)進(jìn)度(經(jīng)由用于行程計數(shù)的全局變量),然后確定此SP線程是否相對于主線程太早或太晚執(zhí)行。提前執(zhí)行策略因此可以被調(diào)節(jié)或者繼續(xù)另一輪預(yù)取(假如未太早執(zhí)行),或進(jìn)入休眠和等待主線程的下一喚醒(假如太早或太晚執(zhí)行),或者與主線程進(jìn)度同步進(jìn)行(通過經(jīng)由全局變量的同步預(yù)取的開始指針)并繼續(xù)執(zhí)行預(yù)取。為提高效率,SP線程在其核心應(yīng)當(dāng)只包括那些確定非推測主線程所需的長等候操作(例如一存儲器加載)順序所必須的指令。因此,可以最小化經(jīng)由函數(shù)內(nèi)嵌從SP線程調(diào)用的函數(shù)數(shù)量。例如,在諸如一列重復(fù)哈希表(hashtables)循環(huán)并在這些表中的每一個執(zhí)行查找(需要遍歷另一列表)的最小生成樹(MST)的應(yīng)用中,內(nèi)嵌是有用的。通過增加SP線程功能性,遞歸函數(shù)也可使得非法加載最小化。由于以下兩個原因遞歸函數(shù)難以直接變換為SP線程遞歸調(diào)用之上的堆棧花銷高得驚人,而且如果難以(或不可能)實(shí)現(xiàn)則提前跳轉(zhuǎn)代碼,因此將遞歸函數(shù)變換到用于SP線程的基于循環(huán)的函數(shù)有時是有用的。為更好地描述用于將單個線程代碼轉(zhuǎn)換為具有推測預(yù)執(zhí)行的優(yōu)化代碼的方法和系統(tǒng)的實(shí)施例,考慮以下單線程偽代碼<prelisting-type="program-listing"> 1main() { 2n=NodeArray 3while(nandremaining) { 4work() 5n->i=n->next->j+n->next->k+n->next->1 6n=n->next 7remaining-- } }</pre>在一個實(shí)施例中,當(dāng)執(zhí)行時,行4需要整體執(zhí)行時間的49.47%,而行5需要大約整體執(zhí)行時間的49.46%。行5也具有整體L2未中的99.95%,這使得它成為采用推測預(yù)執(zhí)行線程優(yōu)化的理想候選者。以下描述了適合運(yùn)行前述具有提高了效率的偽代碼偽代碼的一個例子。由此產(chǎn)生一“主”線程<prelisting-type="program-listing"> 1main() { 2CreateThread(T) 3WaitForEvent() 4n=NodeArray 5while(nandremaining)<dpn="d7"/> { 6work() 7n->i=n->next->j+n->next->k+n->next->1 8n=n->next 9remaining-- 10Everystridetimes 11global_n=n 12global_r=remaining 13SetEvent() } }</pre>行7對應(yīng)單個線程代碼的行5,而且行13SetEvent是一同步觸發(fā)器(其中一API調(diào)用是被靜態(tài)地放置在代碼特定位置,與最初并不知道觸發(fā)時代碼位置的異步觸發(fā)器相反),該同步觸發(fā)器用來啟動以下推測預(yù)執(zhí)行(SP)線程(以下可選地公知為“偵察者”、“工作者”或“幫助者”線程)<prelisting-type="program-listing"> 1T() { 2DoStridetimes 3n->i=n->next->j+n->next->k+n->next->1 4n=n->next 5remaining-- 6SetEvent() 7while(remaining) { 8DoStridetime 9n->i=n->next->j+n->next->k+n->next->1 10n=n->next 11remaining-- 12WaitForEvent()<dpn="d8"/> 13if(remaining<global_r) 14remaining=global_r 15n=global_n } }</pre>行9負(fù)責(zé)提前執(zhí)行所導(dǎo)致的最有效預(yù)取,而行15檢測推后執(zhí)行并通過提前跳轉(zhuǎn)調(diào)節(jié)??偟膩碚f,在主線程中行7的執(zhí)行時間(對應(yīng)單個線程情況下的行5)為19%而在單個線程代碼中為49.46%。L2高速緩存未中是可忽略不計的0.61%而在單線程代碼中為99.95%。推測預(yù)執(zhí)行線程的行9(對應(yīng)主線程的行7)具有26.21%的執(zhí)行時間和97.61%的L2未中,表示可成功承擔(dān)大多數(shù)L2高速緩存未中。為達(dá)到此性能結(jié)果,推測預(yù)執(zhí)行(SP)工作者線程T()基本上在主循環(huán)執(zhí)行指針跟蹤任務(wù),而且不執(zhí)行work()操作。本質(zhì)上,工作者探察或偵察主循環(huán)所采用的加載順序并有效預(yù)取所需數(shù)據(jù)。只存在一個在程序開始時創(chuàng)建的工作者線程,而且它一直存在直到不再有任何循環(huán)迭代執(zhí)行。在某些實(shí)施例中,支持兩個或更多物理硬件線程內(nèi)容并具有與創(chuàng)建一新線程相關(guān)的大花銷的處理器結(jié)構(gòu)可將此工作者線程映射到一第二硬件線程。實(shí)際上,未產(chǎn)生附加線程,而且產(chǎn)生線程的花銷分散在程序中因而實(shí)質(zhì)上是不顯著的。一旦創(chuàng)建SP線程,主線程等待SP線程指示它已完成預(yù)循環(huán)工作。一更完善的調(diào)諧SP線程可探察多于一個用于預(yù)循環(huán)工作的初始指針跟蹤迭代。實(shí)質(zhì)上,SP工作者線程執(zhí)行在先前定義的stride單位大小的所有預(yù)執(zhí)行。當(dāng)對在主線程之前執(zhí)行的預(yù)執(zhí)行線程的迭代數(shù)進(jìn)行有效設(shè)置限制時,這既最小化通信又限制了線程提前執(zhí)行。假如太提前執(zhí)行,預(yù)執(zhí)行產(chǎn)生的預(yù)取不僅臨時取代主線程使用的重要數(shù)據(jù)還可能取代主線程未使用的更早預(yù)取數(shù)據(jù)。另一方面,假如提前運(yùn)行的距離太短,那么該預(yù)取可能太晚而導(dǎo)致無用。在前述一推測預(yù)執(zhí)行工作者線程的偽代碼例子中,工作者線程的預(yù)循環(huán)工作包括執(zhí)行跨距循環(huán),即行2-5之間所示的預(yù)取。如行10-12之間所示,在主線程中的每個跨距回路、當(dāng)前指針的全局復(fù)制以及回路保持?jǐn)?shù)量被更新。而且,假如由于太提前執(zhí)行而安裝了工作者,主線程向工作者線程發(fā)送可繼續(xù)預(yù)取的信號,如行13所示。在預(yù)取多塊跨距長度之后,如行8-11所示,工作者線程等待來自主線程的信號而繼續(xù)。此外,這使得不會在主線程之前太早執(zhí)行工作者。更重要的是,在另一跨距迭代循環(huán)之前,工作者線程檢查其剩余迭代是否比全局版本多。假如剩余迭代是比全局版本多,那么工作者線程推后完成,而且必須通過將其狀態(tài)變量更新為存儲在全局變量中的狀態(tài)變量來“提前跳轉(zhuǎn)”(行13-15)。以下相應(yīng)的“單線程代碼”和改進(jìn)的“推測計算多線程版本”表示利用對應(yīng)前述偽代碼的算法所進(jìn)行的單線程代碼的轉(zhuǎn)換<prelisting-type="program-listing"> 單線程代碼 #include<stdio.h> #include<stdlib.h> typedefstructnodenode; node*pNodes=NULL;//所有結(jié)點(diǎn)數(shù)組的指針 structnode { node*next;//下一結(jié)點(diǎn)的指針 intindex;//此結(jié)點(diǎn)在數(shù)組中的位置 intin;//入度 intout;//出度 inti; intj; intk; intl; intm; }; //函數(shù)說明 voidInitModes(intnum_nodes); intmain(intargc,char*argv[])<dpn="d10"/> { intnum_nodes=500;//結(jié)點(diǎn)總量 node*n; registerintnum_work=200; regiscerintremaining=1;//將要執(zhí)行的迭代數(shù)量 regiscerinti=0; if(argc>1) num_nodes=atoi(argv[1]); if(argc>2) num_work=atoi(argv12]); if(argc>3) remaining=atoi(argv(3)); remaining=num_nodes*remaining; InitNodes(num_nodes); n=&amp;(pNodes); while(n&amp;&amp;remaining) { for(i=0;i<num_work;i++) { _asm(pause}; } n->I=n->next->j+n->next->k+n->next->l+n->next->m; n=n->next; remaining--; } free(pNodes); } voidInitNodes(intnum_nodes) { inti=0; intr=0; node*pTemp==NULL;<dpn="d11"/> pNodes=malloc(num_nodes*sizeof(node)); //給”隨機(jī)”數(shù)產(chǎn)生器一個種子 srand(123456); for(i=0;i<num_nodes;i++) { pNodes[i].index=i; pNodes[i].in=0; pNodes[i].out=0; pNodes[i].i=0; pNodes[i].j=1; pNodes[i].k=1; pNodes[i].l=1; pNodes[i].m=1; } pNodes[num_nodes-1].next=&amp;(pNodes); pNodes[num_nodes-1].out=1; pNodes.in=1; for(I=0;i<num_nodes-1;i++) { r=i; while(r==i||pNodes[r].in==1) r=rand()%num_nodes; pNodes[i].out=1; pNodes[r].in=1; pNodes[i].next=&amp;(pNodes[r]); } }</pre>推測計算多線程版本<prelisting-type="program-listing"> #include<stdio.h> #include<stdlib.h> #include″..\..\IML\libiml\iml.h″ typedefstructnodenode;<dpn="d12"/> typedefstructparamparam; node*pNodes=NULL;//所有結(jié)點(diǎn)數(shù)組的指針 HANDLEevent;//用于跨線程間事件信號 node*global_n=NULL;//共享用于T0/T1通信的變量 intglobal_r=0; structnode { node*next;//下一結(jié)點(diǎn)的指針 intindex;//此結(jié)點(diǎn)在數(shù)組中的位置 intin;//入度 intout;//出度 inti; intj; intk; intl; intm; }; structparam//將傳遞給工作者線程的參量 { node*n;//用來循環(huán)的第一結(jié)點(diǎn)指針 intr;//循環(huán)迭代總量 ints;//″預(yù)見″跨距 } //函數(shù)說明 voidInitNodes(intnum_nodes); voidTask(param*p); intmain(intargc,char*argv[]) { intremaining=1;//循環(huán)迭代總量 intnum_nodes=500;//結(jié)點(diǎn)總量 intstride=4;//工作者線程在等待主線程之前可執(zhí)行的加載量 node*n;<dpn="d13"/> registerintnum_work=200; registerinti=0; registerintj=0; paramP; if(argc>1) num_nodes=atoi(argv[1)); if(argc>2) num_work=acoi(argv[2]); if(argc>3) remaining=acoi(argv(3]); if(argc>4) stride=atoi(argv[4)); remaining=num_nodes*remaining; InitNodes(num_nodes); Event=CreateEvent(NULL,F(xiàn)ALSE,F(xiàn)ALSE,NULL); n=&amp;(pNodes); P.n=n; P.r=remaining; P.s=stride; CreateThread(NULL,0,(LPTHREAD_START_ROUTIHE)Task,&amp;P,0,NULL); //等待工作者線程進(jìn)行預(yù)循環(huán)工作 WaitForSingleObject(event,INFINITE); while(n&amp;&amp;remaining) { for(i=0;i<num_work;i++) { _asm{pause}; } n->I=n->next->j+n->next->k+n->next->l+n->next->m; n=n->next; remaining--;<dpn="d14"/> if(++j>=stride) { j=o; global_n=n; global_r=remaining; SetEvent(event); } } free(pNodes); } voidTask(param*p) { registernode*n=p->n; registerintstride=p->s; registerintlocal_remaining=p->r; registerinti=0; //預(yù)循環(huán)工作 for(i=0;i<stride;i++) { n->i=n->next->j+n->next->k+n->next->l+n->next->m; n=n->next; local_remaining--; } //允許主循環(huán)中的主線程開始 SetEvent(event); //主循環(huán)工作 while(local_remaining) { i=0;<dpn="d15"/> while(i<stride) { n->i=n->next->j+n->next->k+n->next->l+n->next->m; n=n->next; local_remaining--; i++; } WaitForSingleObject(event,INFIMITE); if(local_remaining>global_r) { local_remaining=global_r; n=global_n; } }}voidInitNodes(intnum_nodes){ inti=0; intr=0; node*pTemp=NULL; pNodes=malloc(num_nodes*sizeof(node)); //給“隨機(jī)”數(shù)產(chǎn)生器一個種子 srand(123456); for(I=0;i<num_nodes;i++) { pNodes[i].index=i; pNodes[i].in=0; pNodes[i].out=0; pNodes[i].i=0; pNodes[i].j=1;<dpn="d16"/> pNodes[i].k=1; pNodes[i].l=1; pNodes[il.m=1; } pNodea[num_nodes-1].next=&amp;(pNodes); pNodes(num_nodes-1].out=1; pNodes.in=1; for(I=0;i<num_nodes-1;i++) { r=i; while(r==i||pNodes[r].in==1) r=rand()%num_nodes; pNodes[i].out=1; pNodes[r].in=1; pNodes[I].next=&amp;(pNodes[r]); } }</pre>在用于描述將代碼片斷轉(zhuǎn)換為適合有效操作推測預(yù)執(zhí)行的形式的另一特定實(shí)施例中,推測預(yù)執(zhí)行線程結(jié)構(gòu)如下while(1){等待來自主線程的信號for/while循環(huán)循環(huán)控制間歇預(yù)取來非法加載調(diào)節(jié)未同步線程}被修改用來支持前述結(jié)構(gòu)線程的代碼段為現(xiàn)有的MCF程序<prelisting-type="program-listing"> while(node?。絩oot){ while(node){ if(node->orientation==UP) node->potential=node->basic_arc->cost+node->pred->potential; else/*==DOWN*/<dpn="d17"/> { node->potential=node->pred->potential-node->basic_arc->cost; checksum++; } tmp=node; node=node->child; } node=tmp; while(node->pred){ tmp=node->sibling; if(tmp){ node=tmp; break; } else node=node->pred; } } 設(shè)置SP線程以便 SP線程 g_root=root; SetEvent(g_event_start_a); while(node!=root){ while(node){ if(node->orientation==UP) node->potential=node->basic_arc->cost +node->pred->potential; else/*==DOWN*/ { node->potential=node->pred->potential -node->basicarc->cost; checksum++;<dpn="d18"/> } tmp=node; node=node->child; } node=tmp; while(node->pred){ tmp=node->sibling; if(tmp){ node=tmp; break; } else node=node->pred; } } SP線程 while(1){ WaitForSingleObject(g_event_start_a,INFINITE); sp_root=g_root; sp_tmp=sp_node=sp_root->child; /此處插入SP代碼/ } 重復(fù)循環(huán)控制如下 SP線程 while(1){ WaitForSingleObject(g_event_start_a,INFINITE); sp_root=g_root; sp_tmp=sp_node=sp_root->child; while(sp_node?。絪p_root){ while(sp_node){ sp_tmp=sp_node;<dpn="d19"/> sp_node=sp_node->child; } sp_node=sp_tmp; while(sp_node->pred){ sp_tmp=sp_node->sibling; if(sp_tmp){ sp_node=sp_tmp; break; } else sp_node=sp_node->pred; } } }</pre>當(dāng)通過插入一內(nèi)部環(huán)路計數(shù)器和跨距計數(shù)器來調(diào)節(jié)推后完成或提前執(zhí)行的線程,從而處理同步問題主線程<prelisting-type="program-listing"> g_root=root; SetEvent(g_event_start_a); while(node?。絩oot){ …… …… m_stride_count++; m_loop_count++; } SP線程 while(1){ WaitForSingleObject(g_event_start_a,INFINITE) sp_root=g_root; sp_tmp=sp_node=sp_root->child; while(sp_node?。絪p_root){ ……<dpn="d20"/> …… sp_stride_count++; sp_loop_count++; } } 與主線程的同步如下 主線程 m_stride_count++; m_loop_count++; if(m_stride_count>=STRIDE){ g_node=node; g_loop_count=m_loop_count; SetEvent(g_event_continue); m_stride_count=0; } SP線程 Sp_scride_count++; sp_loop_count++; If(sp_scride_count>=STRIDE){ WaitForSingleObject(g_event_continue,INFINITE); if(g_loop_count>sp_loop_count) {//推后完成、跳轉(zhuǎn)開始 sp_loop_count=g_loop_count; sp_node=g_node; } elseif((g_loop_count+STRIDE)<sp_loop_count) {//又提前、推后并開始 sp_loop_count=g_loop_count; sp_node=gnode; } sp_stride_count=0;<dpn="d21"/> } 對帶有內(nèi)部計數(shù)器的MCF代碼進(jìn)行基本更新如下 主線程 m_stride_count++; m_loop_count++; if(m_stride_count>=STRIDE){ EnterCriticalSection(&amp;cs); g_node=node; g_loop_count=m_loop_count; LeaveCriticalSection(&amp;cs); m_stride_count=0; } SP線程 sp_stride_count++; sp_loop__count++; If(sp_stride_count>=STRIDE){ if(g_loop_count>sp_loop_count) {//推后完成、跳轉(zhuǎn)開始 EnterCriticalSection(&amp;cs); sp_loop_count=g_loop_count; sp_node=g_node; LeaveCriticalSection(&amp;cs); } elseif((g_loop_count+STRIDE)<sp_loop_count) {//又提前、推后并開始 EnterCriticalSection(&amp;cs); sp_loop__count=g_loop_count; sp_node=g_node; LeaveCriticalSection(&amp;cs); } sp-stride_count=0; }</pre>其他MCF代碼增強(qiáng)包括其它通過提前運(yùn)行主線程和循環(huán)體中非法加載的間歇預(yù)取來增強(qiáng)SP線程終止主線程<prelisting-type="program-listing"> while(node?。絩oot){ …… } EnterCriticalSection(&amp;cs); g_node=root; g_loop_count=m_loop_count; LeaveCriticalSection(&amp;cs); SP線程 while(sp_node?。絪p_root){ while(sp_node){ if((sp_loop__count%100)==0|| (ahead_count--)>0) temp=node->basic_arc->cost +node->pred->potential; sp_tmp=sp_node; sp_node=sp_node->child; } …… If(sp_stride_count>=STRIDE){ …… elseif((g_loop_count+STRIDE)<sp_loop_count) {//不推后 ahead_count=15; } sp_stride_count=0; }<dpn="d23"/>}<br/></pre>說明書中所提到的“實(shí)施例”、“一個實(shí)施例”、“一些實(shí)施例”或“其它實(shí)施例”表示與至少一些實(shí)施例中所包括的實(shí)施例相關(guān)的一特殊特征、結(jié)構(gòu)或特性,但不一定是本發(fā)明的所有實(shí)施例。所出現(xiàn)的“實(shí)施例”、“一個實(shí)施例”或“一些實(shí)施例”并不都指相同實(shí)施例。如果說明書表達(dá)一組件、特征、結(jié)構(gòu)或特性時包括“可”、“可以”或“能”,則不需包括特殊組件、特征、結(jié)構(gòu)或特性。如果說明書或權(quán)利要求提到“一”元件,那不表示只有一個元件。假如說明書或權(quán)利要求書提到“一附加”元件,那不排除存在多于一個附加元件。從本公開中獲益的本領(lǐng)域普通技術(shù)人員可以理解,在本發(fā)明的范圍內(nèi)可對前述描述和附圖做許多其他變化。因此,下列權(quán)利要求包括定義本發(fā)明范圍的任何修改。權(quán)利要求1.一代碼轉(zhuǎn)換方法,包括在一主程序中標(biāo)識一組可被動態(tài)激活作為推測預(yù)執(zhí)行線程的指令,并通過一組全局變量指示非推測線程進(jìn)度,允許此推測預(yù)執(zhí)行線程規(guī)范相對于非推測線程的相對進(jìn)度。2.依據(jù)權(quán)利要求1的代碼轉(zhuǎn)換方法,還包括創(chuàng)建推測預(yù)執(zhí)行線程,和在激活之前對所創(chuàng)建的推測預(yù)執(zhí)行線程立即執(zhí)行一等待/休眠操作。3.依據(jù)權(quán)利要求2的代碼轉(zhuǎn)換方法,還包括提供一觸發(fā)器來激活所創(chuàng)建的推測預(yù)執(zhí)行線程。4.依據(jù)權(quán)利要求1的代碼轉(zhuǎn)換方法,還包括在提前執(zhí)行操作之后動態(tài)調(diào)節(jié)推測預(yù)執(zhí)行線程和非推測線程之間的通信。5.依據(jù)權(quán)利要求1的代碼轉(zhuǎn)換方法,還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已落后于由全局變量所指示的非推測線程之后時,推測預(yù)執(zhí)行線程提前跳到非猜測線程的上一通信位置。6.依據(jù)權(quán)利要求1的代碼轉(zhuǎn)換方法,還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已處于由全局變量所指示的非推測線程之前時,推測預(yù)執(zhí)行線程等待直到非推測線程發(fā)信號。7.依據(jù)權(quán)利要求1的代碼轉(zhuǎn)換方法,還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已處于由全局變量所指示的非猜測線程之前時,猜測預(yù)執(zhí)行線程跳回到上一通信位置。8.依據(jù)權(quán)利要求1的代碼轉(zhuǎn)換方法,還包括添加內(nèi)嵌函數(shù)調(diào)用的推測預(yù)執(zhí)行線程。9.依據(jù)權(quán)利要求1的代碼轉(zhuǎn)換方法,其中在程序初始階段動態(tài)發(fā)生推測預(yù)執(zhí)行線程標(biāo)識。10.依據(jù)權(quán)利要求1的代碼轉(zhuǎn)換方法,還包括添加將遞歸函數(shù)變換成基于循環(huán)的函數(shù)的推測預(yù)執(zhí)行線程。11.一種包括具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,所述指令被執(zhí)行時將導(dǎo)致在一主程序中標(biāo)識一組可被動態(tài)激活作為推測預(yù)執(zhí)行線程的指令,并通過一組全局變量指示非推測線程進(jìn)度,允許此推測預(yù)執(zhí)行線程規(guī)范相對于非推測線程的相關(guān)進(jìn)度。12.依據(jù)權(quán)利要求11的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,還包括創(chuàng)建推測預(yù)執(zhí)行線程,和在激活之前對所創(chuàng)建的推測預(yù)執(zhí)行線程立即執(zhí)行一等待/休眠操作。13.依據(jù)權(quán)利要求12的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,還包括提供一觸發(fā)器來激活所創(chuàng)建的推測預(yù)執(zhí)行線程。14.依據(jù)權(quán)利要求11的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,還包括在提前執(zhí)行操作之后動態(tài)調(diào)節(jié)推測預(yù)執(zhí)行線程和非推測線程之間的通信。15.依據(jù)權(quán)利要求11的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已落后于由全局變量所指示的非推測線程之后時,推測預(yù)執(zhí)行線程提前跳到非推測線程的上一通信位置。16.依據(jù)權(quán)利要求11的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已處于由全局變量所指示的非推測線程之前時,推測預(yù)執(zhí)行線程等待直到非推測線程發(fā)信號。17.依據(jù)權(quán)利要求11的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已處于由全局變量所指示的非推測線程之前時,推測預(yù)執(zhí)行線程跳回到上一通信位置。18.依據(jù)權(quán)利要求11的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,還包括添加內(nèi)嵌函數(shù)調(diào)用的推測預(yù)執(zhí)行線程。19.依據(jù)權(quán)利要求11的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,其中在程序初始階段動態(tài)發(fā)生推測預(yù)執(zhí)行線程標(biāo)識。20.依據(jù)權(quán)利要求11的具有存儲在其上的指令的存儲介質(zhì)的產(chǎn)品,還包括添加將遞歸函數(shù)變換成基于循環(huán)的函數(shù)的推測預(yù)執(zhí)行線程。21.一種計算系統(tǒng),包括一優(yōu)化模塊,用來在一主程序中標(biāo)識一組可被動態(tài)激活作為推測預(yù)執(zhí)行線程的指令;以及一同步模塊,包括存儲全局變量的存儲器,此同步模塊通過一組全局變量指示非推測線程的進(jìn)度,允許此推測預(yù)執(zhí)行線程規(guī)范相對于非推測線程的相關(guān)進(jìn)度。22.依據(jù)權(quán)利要求21的計算系統(tǒng),其中此優(yōu)化模塊動態(tài)創(chuàng)建推測預(yù)執(zhí)行線程,和在激活之前對所創(chuàng)建的推測預(yù)執(zhí)行線程立即執(zhí)行一等待/休眠操作。23.依據(jù)權(quán)利要求22的計算系統(tǒng),還包括提供一觸發(fā)器來激活所創(chuàng)建的推測預(yù)執(zhí)行線程。24.依據(jù)權(quán)利要求21的計算系統(tǒng),還包括在提前執(zhí)行操作之后動態(tài)調(diào)節(jié)推測預(yù)執(zhí)行線程和非推測線程之間的通信。25.依據(jù)權(quán)利要求21的計算系統(tǒng),還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已落后于由全局變量所指示的非猜測線程之后時,推測預(yù)執(zhí)行線程提前跳到非推測線程的上一通信位置。26.依據(jù)權(quán)利要求21的計算系統(tǒng),還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已處于由全局變量所指示的非猜測線程之前時,推測預(yù)執(zhí)行線程等待直到非推測線程發(fā)信號。27.依據(jù)權(quán)利要求21的計算系統(tǒng),還包括當(dāng)推測預(yù)執(zhí)行線程的進(jìn)度已處于由全局變量所指示的非推測線程之前時,推測預(yù)執(zhí)行線程跳回到上一通信位置。28.依據(jù)權(quán)利要求21的計算系統(tǒng),還包括添加內(nèi)嵌函數(shù)調(diào)用的推測預(yù)執(zhí)行線程。29.依據(jù)權(quán)利要求21的計算系統(tǒng),其中在程序初始階段動態(tài)發(fā)生推測預(yù)執(zhí)行線程標(biāo)識。30.依據(jù)權(quán)利要求21的計算系統(tǒng),還包括添加將遞歸函數(shù)變換成基于循環(huán)的函數(shù)的推測預(yù)執(zhí)行線程。全文摘要在一個實(shí)施例中,一線程管理方法在一主程序中標(biāo)識一組可被動態(tài)激活作為推測預(yù)執(zhí)行線程的指令。在線程創(chuàng)建和激活之間對推測預(yù)執(zhí)行線程執(zhí)行一等待/休眠操作,而且通過監(jiān)控一組全局變量來指示非推測線程的進(jìn)度,允許推測預(yù)執(zhí)行線程確定其相對于非推測線程的進(jìn)度。文檔編號G06F9/00GK1514365SQ200310124068公開日2004年7月21日申請日期2003年12月31日優(yōu)先權(quán)日2002年12月31日發(fā)明者H·王,P·H·王,R·D·維爾頓,S·M·埃廷格爾,H·塞托,M·B·吉爾卡,S·S·-W·廖,M·R·哈希哈特,H王,-W廖,吉爾卡,哈希哈特,埃廷格爾,王,維爾頓申請人:英特爾公司