專利名稱:改善最近被訪問資源的數(shù)據(jù)局部性的制作方法
技術(shù)領(lǐng)域:
本發(fā)明的技術(shù)領(lǐng)域總地涉及管理存儲器以增加數(shù)據(jù)訪問的效率,更具體地,涉及監(jiān)視和重新排列最近訪問的對象以改善受自動(dòng)管理的堆上的數(shù)據(jù)局部性。
版權(quán)授權(quán)此專利文獻(xiàn)所揭示內(nèi)容的一部分包含受版權(quán)保護(hù)的素材。版權(quán)所有者不反對任何人將此專利文件或此專利所揭示內(nèi)容的傳真復(fù)制,如它出現(xiàn)在專利商標(biāo)事務(wù)所專利文件或記錄中那樣,但此外無論如何都保留所有版權(quán)。
背景技術(shù):
處理器速度和存儲器間增長的不相稱是廣為人知的。許多應(yīng)用程序是以在進(jìn)行諸如無用存儲單元收集等存儲器管理技術(shù)的環(huán)境中執(zhí)行的語言編寫的。此類語言包括,但不限于,諸如C#和Java等語言。用這些語言編寫的應(yīng)用程序往往具有很大的動(dòng)態(tài)工作存儲器頁面集和很差的數(shù)據(jù)局部性。很差的數(shù)據(jù)局部性可能使得應(yīng)用程序執(zhí)行很差,并且不能隨處理器提速很好地作相應(yīng)提升。
較大和多級的高速緩存幫助在一定程度上隱藏存儲器等待時(shí)間。但是,高速緩存存儲器很昂貴,并且由于此代價(jià),芯片上高速緩存(例如,L1高速緩存、ITLB高速緩存和DTLB高速緩存)不太可能和現(xiàn)代應(yīng)用程序的工作負(fù)荷作同樣速度的增長。此外,硬件中的預(yù)取技術(shù)有時(shí)可以減少存儲器等待時(shí)間,但是當(dāng)串行依賴(例如,指針間接)排除預(yù)取地址的適時(shí)具體化時(shí),無規(guī)律數(shù)據(jù)訪問的預(yù)取是很困難的。
因此,用軟件技術(shù)改進(jìn)應(yīng)用程序的數(shù)據(jù)局部性一直是人們感興趣的。在近期的文獻(xiàn)中對靜態(tài)和動(dòng)態(tài)技術(shù)都作了研究和報(bào)告。靜態(tài)技術(shù)依賴于提前程序分析,通常使用剖視數(shù)據(jù),基于引用局部性來協(xié)同定位對象,或在編譯時(shí)間注入預(yù)取指令來隱藏存儲器等待時(shí)間。這些方法的主要優(yōu)點(diǎn)是沒有運(yùn)行時(shí)間的額外開銷;但是,它們可能要受靜態(tài)方法常見的限制約束(例如,處理動(dòng)態(tài)加載的程序集和類的難度,對即時(shí)法的編譯器作完整程序分析的成本)。一部分基于無用存儲單元收集(GC)的系統(tǒng)使用一種復(fù)制機(jī)制在運(yùn)行時(shí)間重新組織所分配的對象,無論這些對象最近有否被訪問過。但是,GC主要用來回收存儲器,并且作為以回收空間為主要目的對堆進(jìn)行壓縮和重新組織的副作用,被動(dòng)地獲得了較佳的空間局部性。
其它基于GC的方法還使用探測在運(yùn)行時(shí)間收集剖視信息,但是這些技術(shù)的剖視成本太高。
發(fā)明內(nèi)容
所描述的各種技術(shù)提供了諸如無用存儲單元收集等加強(qiáng)存儲器管理的方法和系統(tǒng)來增加數(shù)據(jù)局部性。上面所提及的問題至少部分地由本文中所揭示的系統(tǒng)和方法獲得解決。在一個(gè)示例中,一種低額外開銷的技術(shù)收集堆訪問信息,隨后將其用來指導(dǎo)堆的重新組織,以為基于無用存儲單元收集(GC)的系統(tǒng)中的應(yīng)用程序獲得更好的數(shù)據(jù)訪問局部性。剖視和堆的重新組織集中于增加頁密度,以創(chuàng)造低成本但在同時(shí)減少頁差錯(cuò)和高速緩存丟失方面仍然有效的實(shí)用的實(shí)現(xiàn)。
在一個(gè)示例中,GC主要且主動(dòng)用于改進(jìn)存儲器局部性,而不是如以往那樣純粹作為一種被動(dòng)回收空閑存儲器空間的機(jī)制。在一個(gè)此類例子中,一旦檢測到某些程序行為或性能,即使仍然有可供新的分配的空間,也立即調(diào)用或觸發(fā)用于局部性的GC,因此反而不會觸發(fā)空間的GC。在一個(gè)此類例子中,觸發(fā)用于局部性的GC可充分增加無用存儲單元收集的數(shù)量(例如,超過在其它情況下收集所釋放的存儲器空間所需的收集的數(shù)量的50%),并且因?yàn)楦纳频木植啃远匀荒軌蜻_(dá)到總體的提速。
在一個(gè)示例中,用Microsoft的.Net框架的公共語言運(yùn)行庫(CLR)來實(shí)現(xiàn)該方法。CLR使用即時(shí)法(JIT)編譯器將MSIL(Microsoft中間語言)二進(jìn)制碼翻譯成本機(jī)代碼,并使用世代式無用存儲器單元收集器來管理堆。用若干用C#編寫的示例性應(yīng)用程序評估了一種經(jīng)由無用存儲器單元收集改進(jìn)數(shù)據(jù)局部性的示例性方法;但該方法適用于目標(biāo)為復(fù)制基于GC的系統(tǒng)的以任何語言編寫的應(yīng)用程序。但是,所描述的技術(shù)不需要無用存儲器單元收集。
在另一個(gè)示例中,一種方法監(jiān)視在堆上被訪問的對象。在一個(gè)此類例子中,設(shè)置(或計(jì)數(shù))一個(gè)或多個(gè)比特以指示某對象被訪問。這一個(gè)或多個(gè)比特可以在該對象自身內(nèi)部或靠近該對象,或者可以位于存儲器中的其它位置。在另一個(gè)示例中,并非所有的訪問都被計(jì)數(shù)。相反,該方法根據(jù)采樣周期對被訪問的對象進(jìn)行周期性的監(jiān)視。在一個(gè)此類例子中,該方法還監(jiān)視程序行為以判定何時(shí)執(zhí)行堆的重新組織。當(dāng)所監(jiān)視的程序行為有所指示,該方法即重新組織堆。在一個(gè)示例中,重新組織的機(jī)制將最近被訪問的對象群集到堆中的同一區(qū)域中。在另一個(gè)示例中,重新組織的機(jī)制將最近在一個(gè)采樣周期期間被訪問的對象群集到堆的同一區(qū)域中。在一個(gè)示例中,最近被訪問的對象的群集被放置到堆的一個(gè)或多個(gè)頁上。在另一個(gè)示例中,該方法清除指示某對象被訪問的比特,并返回以監(jiān)視對象訪問和程序行為。
以下具體描述將使其它特征和優(yōu)點(diǎn)顯而易見,在此之前是附圖的參考。
圖1是優(yōu)化堆的數(shù)據(jù)局部性的示例性方法的流程圖。
圖2是優(yōu)化堆的數(shù)據(jù)局部性的示例性系統(tǒng)的框圖。
圖3是經(jīng)由多個(gè)具有變動(dòng)訪問速度的等級管理存儲器的示例性系統(tǒng)的框圖。
圖4是創(chuàng)建執(zhí)行優(yōu)化的可執(zhí)行代碼的示例性方法的圖。
圖5所示是將示例性對象分布遍及存儲器中的各個(gè)頁以執(zhí)行優(yōu)化的示例圖。
圖6是示例性世代式無用存儲單元收集方法和系統(tǒng)圖。
圖7是用無用存儲單元收集優(yōu)化堆的數(shù)據(jù)局部性的示例性系統(tǒng)的框圖。
圖8是實(shí)現(xiàn)所描述的技術(shù)的分布式計(jì)算機(jī)系統(tǒng)的框圖。
具體實(shí)施例方式
優(yōu)化數(shù)據(jù)局部性的示例性方法圖1是優(yōu)化堆的數(shù)據(jù)局部性的示例性方法的流程圖。如圖所示,方法100監(jiān)視被訪問的對象,監(jiān)視優(yōu)化的度量、并在一個(gè)或多個(gè)堆頁上重新組織被訪問的對象。
在102,該方法監(jiān)視在堆上被訪問的對象。例如JIT編譯器探測讀或?qū)懚阎械臄?shù)據(jù)對象的操作。保留指示哪些對象被訪問的記錄。在一個(gè)例子中,該記錄是對象本身中被設(shè)置成指示該對象最近被訪問的一個(gè)比特。在另一個(gè)例子中,該記錄是某個(gè)單獨(dú)位矢量中的一個(gè)比特。在又一個(gè)例子中,處理器提供一種記錄最近被訪問的所有對象的地址(例如,記錄所有當(dāng)前在高速緩存中的地址)或引發(fā)頁差錯(cuò)的地址的機(jī)制或手段。
其時(shí),在104,該方法監(jiān)視各度量以判定何時(shí)執(zhí)行數(shù)據(jù)局部性的優(yōu)化。例如,性能度量可以是對象分配率、DTLB缺失率、高速緩存缺失率、性能計(jì)數(shù)器、對象引用計(jì)數(shù)器、或定時(shí)器。當(dāng)被監(jiān)視的度量指示是該為局部性而重新組織堆的時(shí)候時(shí),則該方法執(zhí)行步驟106。
在106,該方法首先標(biāo)識最近被訪問的對象,并隨即將它們聚集到堆中若干連續(xù)的頁上。例如,經(jīng)探測的代碼在被訪問的對象中設(shè)置一個(gè)比特,或在被訪問對象的比特表中設(shè)置一個(gè)比特。例如,如果經(jīng)探測的代碼在被訪問的對象中設(shè)置一個(gè)比特或在被訪問對象的比特表中設(shè)置一個(gè)比特,則隨即在堆上將這些對象群集到一起。在另一個(gè)例子中,處理器所提供的一個(gè)操作說明堆上哪些對象地址最近被訪問過。在另一個(gè)例子中,處理器所提供的一個(gè)操作指示哪些地址請求引發(fā)的DTLB丟失。在一個(gè)例子中,對應(yīng)于被訪問對象的訪問比特或計(jì)數(shù)器隨即被復(fù)位。在另一個(gè)例子中,不是將訪問比特或計(jì)數(shù)器當(dāng)即復(fù)位,而是隨時(shí)間過去慢慢復(fù)位。
在108,一旦已經(jīng)為數(shù)據(jù)局部性將堆優(yōu)化,則該方法返回步驟102和104。
優(yōu)化數(shù)據(jù)局部性的示例性系統(tǒng)圖2是優(yōu)化堆的數(shù)據(jù)局部性的示例性系統(tǒng)的框圖。
計(jì)算機(jī)系統(tǒng)200包括一個(gè)或多個(gè)處理器202,芯片上高速緩存204、被監(jiān)視并為數(shù)據(jù)局部性進(jìn)行優(yōu)化的一個(gè)或多個(gè)運(yùn)行程序208、為改進(jìn)數(shù)據(jù)局部性而監(jiān)控程序的模區(qū)塊206、包括供運(yùn)行程序208使用的工作數(shù)據(jù)頁(例如,頁、段、等等)的堆216的隨機(jī)存取存儲器(RAM)210、芯片外高速緩存212、磁盤驅(qū)動(dòng)器或其它二進(jìn)制存儲設(shè)備214、和網(wǎng)絡(luò)連接218。處理器執(zhí)行程序208、206、220,這些程序包括指令、數(shù)據(jù)和/或狀態(tài)。當(dāng)執(zhí)行被監(jiān)視程序208時(shí),按照需要將該程序的數(shù)據(jù)頁從存儲214和/或網(wǎng)絡(luò)218取回到堆216中。
在一個(gè)示例中,被監(jiān)視程序208是在執(zhí)行前要進(jìn)一步編譯成本機(jī)代碼的中間語言(IL)代碼。在這樣一個(gè)例子中,編譯器206編譯并探測該程序。在另一個(gè)例子中,該程序已經(jīng)是本機(jī)二進(jìn)制碼的形式,并且對該本機(jī)二進(jìn)制代碼執(zhí)行探測206。在另一個(gè)例子中,探測206增加處理器支持的指令,以標(biāo)識在執(zhí)行期間被訪問的對象或地址。
探測程序208,使它記錄下在程序208執(zhí)行時(shí)被訪問的堆216中的對象。還探測該程序,使它還監(jiān)視各度量并觸發(fā)優(yōu)化模區(qū)塊220。諸如TLB、DTLB或高速緩存的丟失等各種度量可用于觸發(fā)優(yōu)化。用于觸發(fā)優(yōu)化的其它可能的度量是存儲器分配率、對象引用計(jì)數(shù)、以及以下所討論的其它度量。一旦執(zhí)行經(jīng)探測的程序,并且觸發(fā)了優(yōu)化,則優(yōu)化模塊220重新組織堆216的至少一個(gè)存儲器頁(或區(qū)段)。例如,優(yōu)化機(jī)制將所有被訪問的對象(例如,熱對象)放置到堆上某個(gè)單獨(dú)的頁(或某組頁)上。堆上這個(gè)(或這組)熱對象的頁稱作熱頁。
因此,系統(tǒng)探測一程序以監(jiān)視執(zhí)行期間被訪問的對象(程序監(jiān)視),監(jiān)視該程序中觸發(fā)堆220優(yōu)化的性能指示器(性能監(jiān)視),并將被訪問的對象重新組織到存儲器中的一個(gè)群集中(例如,將堆上一個(gè)或多個(gè)相互靠近的對象的集合重新組織到單個(gè)頁上,或重新組織到若干連續(xù)的頁上,等等),從而由于增強(qiáng)的數(shù)據(jù)局部性(數(shù)據(jù)局部性優(yōu)化)而提高程序性能。此外,一旦將對數(shù)據(jù)進(jìn)行局部性優(yōu)化,系統(tǒng)即開始監(jiān)視經(jīng)優(yōu)化的程序。因此,該系統(tǒng)是動(dòng)態(tài)的和進(jìn)行中的。
示例性存儲器配置圖3是經(jīng)由多個(gè)具有變動(dòng)訪問速度的等級管理存儲器的示例性系統(tǒng)的框圖。
現(xiàn)代計(jì)算機(jī)300包括一個(gè)或多個(gè)中央處理單元302(CPU)其中包括一個(gè)或多個(gè)處理器304和各級存儲器,包括但不限于,芯片上高速緩存306、308、310,芯片外高速緩存312、314,隨機(jī)存取存儲器(RAM)316,磁盤存儲318和許多其它形式的存儲器。計(jì)算機(jī)執(zhí)行已處理為可執(zhí)行文件的程序。處理器從存儲器取回指令,將指令解碼,并執(zhí)行已解碼的指令來執(zhí)行各種功能。為了改進(jìn)性能和速度,計(jì)算機(jī)使用各種等級的存儲器來增加當(dāng)需要下一個(gè)指令或數(shù)據(jù)時(shí),該指令或數(shù)據(jù)可用的可能性。例如,處理器檢查數(shù)據(jù)和指令(資源)是否在高速緩存中,而不是每次需要資源的時(shí)候都在RAM中查找。從高速緩存獲得所需的資源比從RAM或磁盤獲得更快,因?yàn)榭梢栽谳^少的時(shí)鐘周期內(nèi)完成。所描述的方法和系統(tǒng)通過減少檢索資源所需的時(shí)間改善了計(jì)算性能。
CPU性能的進(jìn)步一直以來比存儲器性能的進(jìn)步快得多。這導(dǎo)致了程序的運(yùn)行速度并沒有隨處理器速度增長而提速很多。一種解決方案是將在離芯片更近處構(gòu)建更大的高速緩存存儲器,但該解決方案是困難的,因?yàn)楦咚倬彺娲鎯ζ骱馨嘿F。因此,處理的相對速度受到存儲器速度的支配要比受到解碼和執(zhí)行指令的速度的支配來得大。例如,奔騰(Pentium)IV提速了3或4倍,但應(yīng)用程序并未能提速3倍,因?yàn)樘幚砥髟诘却龜?shù)據(jù)或指令從存儲器傳入,在此例中即可顯見上述說法。時(shí)間消耗在將虛擬地址翻譯成存儲器中的物理地址,這是由翻譯后備緩沖器(TLB)306、308完成的。許多系統(tǒng)具有指令后備緩沖器(ITLB)306,和數(shù)據(jù)后備緩沖器(DTLB)308。因?yàn)槌绦蚩删哂斜萊AM中的可用空間大的虛擬地址空間,部分程序執(zhí)行狀態(tài)(例如,代碼/數(shù)據(jù)頁)按照需要在RAM 316和存儲318之間傳送。
TLB用于將虛擬地址空間中當(dāng)前可用的內(nèi)容翻譯成其在物理存儲器中的定位。TLB高速緩存是昂貴的硬件,因此設(shè)計(jì)者寧愿減小該尺寸。當(dāng)程序執(zhí)行請求某個(gè)地址,但TLB高速緩存判定該地址不在RAM 316中,則它遇到了頁差錯(cuò)。如果包含該地址的頁駐留在存儲器中,則該頁差錯(cuò)稱作軟頁差錯(cuò),并且需要數(shù)百個(gè)時(shí)鐘周期來更新該地址的TLB條目。如果包含該地址的頁不駐留在存儲器中,則必需將其從存儲中調(diào)入存儲器中。在這中情形中,頁差錯(cuò)稱作硬頁差錯(cuò),并且可能需要數(shù)百萬條指令將該頁從磁盤調(diào)入。當(dāng)處理器請求某個(gè)同時(shí)在TLB和高速緩存310、312、314中已可用的地址,則翻譯將是非??斓?。因此,存儲器管理涉及管理哪些頁(區(qū)塊、段、等等)可用,在最少的時(shí)鐘周期內(nèi)如何增加所需的資源可供處理器使用的可能性,等等。
純粹為了時(shí)間差別的相對比較,查看各種高速緩存和存儲器速度的例子是很有趣的。如果處理器請求的資源在一級(L1)高速緩存中可用,則可在1-3個(gè)時(shí)鐘周期內(nèi)獲得該資源。如果處理器請求的資源在L2高速緩存中可用,則可在10-50個(gè)時(shí)鐘周期內(nèi)獲得該資源??稍诖蠹s20-100個(gè)時(shí)鐘周期內(nèi)獲得L3高速緩存中的資源,在大約500個(gè)時(shí)鐘周期內(nèi)獲得存儲器中的資源,要消耗顯著長得多的時(shí)間才能獲得存儲中的資源。按照需要將資源按頁(例如,4K字節(jié))從存儲調(diào)入到存儲器中,并按需要將諸如區(qū)塊等較小尺寸的資源調(diào)入高速緩存(例如,64-128字節(jié))。同樣,這些例子不控制本討論內(nèi)容或?qū)⑵湎拗朴谏婕澳壳盎蛭磥韺?shí)際或相對差別的上下文中,它們純粹是旨在為本討論提供上下文。
因此,系統(tǒng)探測一程序以在執(zhí)行期間監(jiān)視被訪問的對象(程序監(jiān)視);監(jiān)視程序中觸發(fā)堆320優(yōu)化的性能指示器(性能監(jiān)視);和將被訪問的對象重新組織到存儲器中的單個(gè)頁322上,從而由于改善的數(shù)據(jù)局部性而提高了程序性能(數(shù)據(jù)局部性優(yōu)化)。此外,一旦將對數(shù)據(jù)進(jìn)行局部性優(yōu)化,系統(tǒng)即開始監(jiān)視經(jīng)優(yōu)化的程序。因此,該系統(tǒng)是動(dòng)態(tài)的和進(jìn)行中的。
示例性編譯圖4是創(chuàng)建可執(zhí)行代碼的示例性方法400的圖。在一個(gè)例子中,按照需要編譯404源代碼,以可執(zhí)行的形式分布406(例如,X86)并調(diào)入存儲器。例如,某些代碼的二進(jìn)制碼可以在任何兼容環(huán)境中運(yùn)行。在一個(gè)此類例子中,兼容的二進(jìn)制代碼是可以在任何X86環(huán)境中執(zhí)行的可移植的可執(zhí)行碼(PE)。此模型可以在用諸如C和C++等高級編程語言編寫的程序中找到。
在另一個(gè)例子中,源代碼402被編譯成中間級代碼408(例如,MSIL、Java、等等),可為執(zhí)行可執(zhí)行碼的處理器(例如,X86、X64、等等)將這些代碼進(jìn)一步編譯410成本機(jī)可執(zhí)行碼412。在一個(gè)此類例子中,當(dāng)需要執(zhí)行時(shí)(例如,當(dāng)從存儲、網(wǎng)絡(luò)等調(diào)入到存儲器時(shí)),即時(shí)(JIT)編譯器將中間代碼翻譯成本機(jī)代碼。
包括無用存儲單元收集在內(nèi)的存儲器管理在包括圖4所構(gòu)想的那些環(huán)境等許多計(jì)算環(huán)境中被使用,并且單獨(dú)的計(jì)算環(huán)境可使用這些編譯方法中的任何一種。例如,可探測414現(xiàn)有二進(jìn)制碼以記錄在執(zhí)行期間那些對象被訪問,也可以在JIT編譯期間進(jìn)行探測416。有趣的是,本文所描述的局部性優(yōu)化往往在JIT編譯中特別有用,因?yàn)橥ǔ_@些語言更多地依賴于存儲器管理來清除程序不再引用(例如,經(jīng)由可達(dá)性分析、引用計(jì)數(shù)、等等)的對象。
某些高級語言要求程序員對其程序預(yù)期需要的存儲器進(jìn)行分配和解除分配。其它語言或運(yùn)行時(shí)間庫允許程序員依靠無用存儲單元收集來完成解除分配。無用存儲單元收集涉及在堆中標(biāo)識哪些對象仍在使用,并棄置任何不再被引用的對象。
以往,當(dāng)沒有足夠空間以滿足新的分配請求時(shí)才調(diào)用無用存儲單元收集,判定為不再被引用的對象所占據(jù)的空間被釋放并使其可供新的對象使用。因此,GC主要被視為一種按照需要回收存儲器的方法。例如,當(dāng)程序需要多于目前可用數(shù)量的存儲器時(shí),則遍歷堆以尋找該堆上哪個(gè)存儲器可達(dá)??蛇_(dá)的存儲器被組裝到頁上,并使被釋放的空間可用于處理器所請求的資源。因此,僅當(dāng)不能滿足新的分配請求時(shí)才觸發(fā)GC。
在本技術(shù)中,將GC視作一種改善數(shù)據(jù)局部性并因而提高性能的方法。在一個(gè)此類例子中,首先將GC視作為性能目的而改善局部性的方法,其次將其視為按需釋放存儲器的方法。盡管有跟蹤熱對象和將被訪問的對象排列在一起的額外開銷,GC仍常常導(dǎo)致性能的提高。在一個(gè)例子中,即使比純粹用于回收空間所執(zhí)行的次數(shù)多執(zhí)行50%次GC,凈性能仍然較佳。因?yàn)闊釋ο蟊唤M裝到頁上,所以處理器也需要被移到高速緩存中的部分所組裝的熱頁的可能性增加了。因此將對象組裝到一個(gè)頁或一組頁上不但在堆上,而且在放置該頁部分的高速緩存中改善了空間局部性。用熱對象組裝頁的副作用是增加了高速緩存的利用率。
有趣的是,為每個(gè)被訪問的對象設(shè)置一個(gè)比特足以用來跟蹤被訪問的對象。但是,每個(gè)對象用幾個(gè)比特來計(jì)訪問次數(shù)指示了哪些對象最經(jīng)常被訪問。這允許將對象組裝到頁上處有更大的粒度。
示例性局部性應(yīng)用程序往往在訪問存儲器時(shí)表現(xiàn)出時(shí)間性的局部性,即如果某對象最近被訪問,則不久它會再次被訪問。此外,如果應(yīng)用程序訪問靠近其最近訪問的對象的對象,則稱其為具有很好的空間局部性。很差的空間局部性會使得對象的訪問遍及整個(gè)存儲器,導(dǎo)致TLB/高速緩存和RAM的低利用率,并因此導(dǎo)致執(zhí)行的低性能。通過監(jiān)視哪些對象最近期被訪問并調(diào)用優(yōu)化方法來協(xié)同定位這些熱對象,則很可能在較后階段執(zhí)行中改善空間局部性。假定當(dāng)程序操作時(shí)熱對象組可能改變,則繼續(xù)監(jiān)視和不斷地或周期性地優(yōu)化是很重要的。
并非必需在無用存儲單元收集期間,或從無用存儲單元調(diào)用此存儲器優(yōu)化技術(shù)。在一個(gè)實(shí)施例中,局部性優(yōu)化收集獨(dú)立于無用存儲單元收集進(jìn)行操作。在一個(gè)此類例子中,存儲器的壓力使得現(xiàn)有無用存儲單元收集方法釋放存儲器,但是如本文所述,任何需要的時(shí)候,都可調(diào)用局部性優(yōu)化。
在另一個(gè)例子中,提供局部性優(yōu)化方法,作為無用存儲單元收集的額外優(yōu)化,這是很方便的,因?yàn)楣芾矶训默F(xiàn)有方法和數(shù)據(jù)結(jié)構(gòu)可用于支持局部性優(yōu)化。例如,在無用存儲單元收集期間,在標(biāo)識了活的對象的同時(shí),還可識別活的和熱的對象,并將其組裝到熱頁中。
圖5所示是遍及存儲器中的各個(gè)頁的示例性對象的示意圖。在此例中,每個(gè)柵格502都表示堆500上的一個(gè)頁,柵格內(nèi)部的對象表示活對象504或被棄置(例如,被釋放的或不再被引用的)對象506。堆通常占據(jù)一部分RAM。在任何給定時(shí)刻,基于可用高速緩存的大小,堆的一些部分在較快的高速緩存存儲器中可用。TLB將虛擬地址空間映射到物理地址,并指示虛擬地址空間的哪些部分可被迅速翻譯成RAM中的物理地址。
隨著時(shí)間過去,有效對象遍及整個(gè)堆,并且隨著活對象之間夾雜著死對象,存儲器變得越來越支離破碎,這使得情況更加糟糕。這導(dǎo)致很差的空間局部性。很差的數(shù)據(jù)局部性的副作用之一是需要消耗更多的時(shí)間按照處理器的需要將存儲器區(qū)塊調(diào)入和調(diào)出高速緩存,及在訪問未在DTLB條目中呈現(xiàn)的地址時(shí)更新DTLB。
最后,當(dāng)堆充滿了對象,并且請求更多的對象分配時(shí),基于存儲器的壓力觸發(fā)無用存儲單元收集方法。
在一個(gè)例子中,為了克服此很差的空間局部性,在每個(gè)被訪問的對象中設(shè)置一個(gè)比特508。當(dāng)觸發(fā)了局部性優(yōu)化,這些具有被設(shè)置的比特的對象被集合到存儲器中單獨(dú)一組連續(xù)頁上。在另一個(gè)例子中,對象以外的一個(gè)熱比特表指示哪些對象被訪問。無論哪種方法,此熱比特?cái)?shù)據(jù)指示哪些對象要放到熱頁上。
無用存儲單元收集支持的示例性局部性優(yōu)化圖6是示例性世代式無用存儲單元收集方法和系統(tǒng)的圖。邏輯上將堆600分成若干代(例如,G0、G1和G2)。邏輯上將這些代視為堆的各個(gè)部分,通常用3代來劃分堆。例如,有最近期配給的帶有空閑空間的最新一代602的對象,較老一代對象604,和最老一代對象606。通常,根據(jù)從初始分配開始的時(shí)間來查看這些對象,其中最新的對象和可用的空閑空間邏輯上看成在第一代602中。堆的邏輯視圖存儲在指示世代邊緣608的數(shù)據(jù)結(jié)構(gòu)中,并附有空閑空間開始位置的指示。
當(dāng)空閑空間由于新的分配而減少,基于存儲器的壓力(例如,對更多存儲器空間實(shí)際或預(yù)期的需求)觸發(fā)無用存儲單元收集。例如,當(dāng)請求對象分配而可用存儲器太小,或者可用存儲器低于某較佳或合乎需要的閾值時(shí)。
在存儲器迫使的無用存儲單元收集期間,標(biāo)識出活的對象,收集了無用存儲單元(例如,不再可達(dá)的對象、不再被引用的對象、等等)并將其從堆移除,并且隨著被釋放存儲器邏輯上被移到最新的一代,各個(gè)世代的大小隨之調(diào)整。
例如,可對第一代602進(jìn)行若干次無用存儲單元收集。當(dāng)對較新一代的存儲器收集不再產(chǎn)生超過合意閾值的空閑存儲器時(shí),可對較老的一代604進(jìn)行無用存儲空間收集。例如,當(dāng)所觸發(fā)的第一代的無用存儲單元收集不再產(chǎn)生足夠的空閑存儲器時(shí),它將觸發(fā)第二代的無用存儲單元收集。在進(jìn)行任何第三代的無用存儲單元收集之前,可能發(fā)生若干次第二代的無用存儲單元收集。一旦第一和第二代無用存儲單元收集沒有收集到足夠的空閑存儲器,即觸發(fā)第三代的無用存儲單元收集。隨著時(shí)間過去,死的對象被移除,而活的對象被壓縮。
有各種無用存儲單元收集的方法,諸如“標(biāo)記和清掃”,其中死的對象被放到空閑列表上,并且“標(biāo)記并壓縮”,而在堆中活的對象被壓縮到一起。一旦本領(lǐng)域技術(shù)人員閱讀此說明書,即可改編或增強(qiáng)這些無用存儲單元收集方法(及其變體、組合和改進(jìn))中的任何一種以支持本文所述的局部性優(yōu)化。
這些現(xiàn)有無用存儲單元收集技術(shù)(例如,世代無用存儲單元收集)的副作用之一是稍微改善了數(shù)據(jù)局部性。例如,僅僅靠將死的對象從堆中移除(無論是從哪個(gè)世代將其移除),即增加了各個(gè)頁提供更好空間局部性的可能性。僅出于說明的目的,本討論將繼續(xù)復(fù)制世代無用存儲單元收集。
復(fù)制世代無用存儲單元收集的凈效果是對象按照分配的大約次序保留在堆上,并且其它邏輯分區(qū)按照各個(gè)世代組合,隨著時(shí)間過去可以使用各種方法對此進(jìn)行調(diào)整。死的對象被移除,隨其后的活的對象被移上來。因此,分配的順序?qū)⒈痪S持。這是基于分配的順序提供最佳局部性的理論,但此理論不總為真。
例如,Chilimbi等人的“Using Generational Garbage Collection to ImplementCache Conscious Data Placement”(用世代無用存儲單元收集改善高速緩存已知的數(shù)據(jù)布局)1998年10月(Chilimbi),集中于以高速緩存友好的方法來對數(shù)據(jù)進(jìn)行布局以提高程序效率。例如,Chilimbi監(jiān)視對象序列次序來決定應(yīng)以什么次序?qū)ο罂傃b在一起。此概念要求監(jiān)視對象被訪問的次序,并試圖按該次序重新排列這些對象。在運(yùn)行時(shí)間獲取所有這些信息及分析這些信息的額外開銷常常過高。
相反,所述優(yōu)化機(jī)制監(jiān)視在每兩次優(yōu)化之間或在時(shí)間間隔期間哪些對象被訪問,并在觸發(fā)了優(yōu)化時(shí),將這些對象組合到堆上的一個(gè)或多個(gè)熱頁上。有趣的是,盡管并未直接試圖為提高高速緩存的利用率而收集剖視數(shù)據(jù),以本文所述的方法將熱對象放到堆的同一個(gè)或多個(gè)頁上的副作用之一是高速緩存終止被更聰明地利用。
因此,復(fù)制世代無用存儲單元收集是一種適應(yīng)于本文所述的優(yōu)化的有趣的環(huán)境。它遍歷各個(gè)對象以標(biāo)識所有活的對象,并基于其分配次序?qū)⑵鋲嚎s,可利用此來標(biāo)識熱對象,并隨機(jī)將其按照需要的順序組裝在一起。因此,這些優(yōu)化不受復(fù)制世代無用存儲單元收集的限制,而是簡單地由其支持。
示例性低額外開銷的剖視在一個(gè)例子中,JIT編譯器被改編成探測訪問堆的操作。經(jīng)探測的代碼監(jiān)視堆上的對象何時(shí)被訪問。在一個(gè)例子中,在每個(gè)對象內(nèi)部引入(例如,附加)一個(gè)存儲器區(qū)域,以指示該對象是否被訪問過。在另一個(gè)例子中,每個(gè)對象內(nèi)部的一個(gè)已知未被使用的存儲器區(qū)域(例如,一個(gè)比特,或多個(gè)比特)被標(biāo)記以標(biāo)識該對象被訪問過。例如,對象頭部具有可用于各種理由的可用空間。設(shè)置一個(gè)比特,或如果使用多個(gè)比特,則記一次訪問,在每兩次優(yōu)化之間或某時(shí)間間隔期間被訪問的對象被組裝到熱頁上,訪問比特(或訪問計(jì)數(shù)器)被清除,從而它們即可為下一次熱對象的收集記錄它們是否將被訪問(或從0開始記的訪問次數(shù))。但是,在頭部中設(shè)置熱對象指示比特不是必需的。這個(gè)(些)比特可以放在對象中的任何位置或其它地方。注意此處無需記錄任何序列信息。
例如,熱對象比特表可為每個(gè)對象表示一個(gè)比特。這將需要更多的存儲器,但在許多例子中它可能較佳,因?yàn)樵跇?biāo)識了熱對象之后,更容易清除這些比特。
在另一個(gè)例子中,創(chuàng)建位矢量,它是堆的較小版本。在一個(gè)此類例子中,位矢量中的各個(gè)比特對應(yīng)于堆的地址或區(qū)域,矢量中的一個(gè)比特被設(shè)置以指示堆的某個(gè)地址或區(qū)域被訪問。可以在例如每兩次熱頁優(yōu)化間,或當(dāng)為存儲器的壓力執(zhí)行了無用存儲單元收集時(shí),簡單地復(fù)位該位矢量。
當(dāng)程序隨著時(shí)間過去而發(fā)展時(shí),熱對象也在發(fā)展,并且熱頁隨著熱對象的發(fā)展而發(fā)展。本文所述的低額外開銷的剖視允許動(dòng)態(tài)改變熱頁來提高程序性能。
示例性組裝的對象頁如稍后將討論的,單獨(dú)或組合的一個(gè)或多個(gè)度量可用于判定何時(shí)要觸發(fā)局部性優(yōu)化(例如,分配率、性能度量、等等)。一旦觸發(fā)了數(shù)據(jù)局部性的優(yōu)化,即標(biāo)識出具有表示其為熱對象的對應(yīng)比特的活的對象,并將其放到熱頁上。在另一個(gè)例子中,有多個(gè)熱對象的頁。在一個(gè)實(shí)現(xiàn)中,首先將所有熱對象從堆復(fù)制出來,并將其填充到臨時(shí)緩沖,以允許空間目的的傳統(tǒng)的無用存儲單元收集照常進(jìn)行,隨后將所有熱對象的集合放在堆較新的一端,而最近分配的對象將靠近這些熱的活對象放置。此實(shí)現(xiàn)以很低的額外開銷大大改善了數(shù)據(jù)的局部性。
組裝的對象頁的示例性優(yōu)化在另一個(gè)例子中,當(dāng)在局部性目的的GC期間遇到熱對象(例如,如設(shè)定的比特所示),則評估這些熱對象,以查看它們還指向哪些其它熱對象。在一個(gè)此類例子中,當(dāng)某熱對象指向另一個(gè)熱對象,那么不但兩個(gè)熱對象都被放到熱頁上,而且將它們彼此靠近地放置。這提供了一種低額外開銷的方法,增加了在熱頁的部分被移到高速緩存中時(shí),被移到高速緩存中的對象很可能會被一個(gè)接一個(gè)地引用的可能性。這常常會提高有效性能。
具有很差數(shù)據(jù)局部性的示例性程序以下表A示出4個(gè)用C#編寫的測試應(yīng)用程序的頁密度。這些數(shù)字是用動(dòng)態(tài)翻譯器運(yùn)行這些應(yīng)用程序并記錄存儲器讀和寫而獲得的。這些數(shù)字不包括對堆棧頁的引用。密度度量等于在按頁的大小劃分的某個(gè)頁上讀或?qū)懙莫?dú)特字節(jié)的個(gè)數(shù)。在此例中,間隔設(shè)置在106次引用。以下表A說明數(shù)據(jù)頁的使用效率很低,這通常意味著很差的空間局部性。
示例性系統(tǒng)在一個(gè)例子中,優(yōu)化復(fù)制世代無用存儲單元收集器以改善數(shù)據(jù)局部性。例如,可以在包括無用存儲單元收集在內(nèi)的存儲器管理中使用虛擬機(jī)的方式來使用本方法。在此例中,關(guān)于虛擬機(jī)的大多數(shù)其它細(xì)節(jié)方面,該系統(tǒng)是不可知的。
圖7示出該系統(tǒng)一個(gè)可能的實(shí)施例的體系結(jié)構(gòu)總覽700。即時(shí)(JIT)編譯器702被配置成取一個(gè)中間語言的表示704(例如,MSIL)并將其編譯成某個(gè)特定體系結(jié)構(gòu)的機(jī)器代碼706。可將JIT編譯器修改成在已編譯的代碼中插入輕量級的探測。已探測代碼708標(biāo)記最近被訪問的對象??梢栽谶\(yùn)行時(shí)間插入監(jiān)視代碼(例如,公共語言運(yùn)行庫(CLR)或Java運(yùn)行庫),從而在應(yīng)用程序運(yùn)行時(shí)收集度量。監(jiān)視代碼可以使用監(jiān)視數(shù)據(jù)和試探來觸發(fā)局部性目的的GC。在局部性目的的GC期間,可標(biāo)識出標(biāo)記為最近被訪問(熱)的對象,并將它們協(xié)同定位到若干與堆的其余頁分開的頁上??梢元?dú)立于一旦檢測到存儲器壓力時(shí)即被觸發(fā)的常規(guī)GC,觸發(fā)局部性目的的GC。
示例性的頁優(yōu)化對高速緩存優(yōu)化當(dāng)為局部性目的排列數(shù)據(jù),兩個(gè)選擇是或者為頁局部性目的進(jìn)行優(yōu)化,或者為高速緩存局部性目的進(jìn)行優(yōu)化。
在一個(gè)例子中,數(shù)據(jù)頁的頁密度增加是有利的。例如,收集頁優(yōu)化的剖視信息的成本可能較低。因?yàn)轫?通常4千字節(jié))比高速緩存行(通常64-128字節(jié))要大幾個(gè)量級,所以不需要獲得數(shù)據(jù)訪問的精確時(shí)間順序來進(jìn)行有效的組裝。因?yàn)椤笆占鳌钡某叽巛^大,所以能承受得起較松散地組裝數(shù)據(jù)。注意到,僅僅通過增加頁密度,就同樣地增加了組裝數(shù)據(jù)以獲較佳的高速緩存利用率(通過移除冷的居間對象)的機(jī)會。這對許多程序來說導(dǎo)致了顯著的高速緩存的利益,有效地作為頁優(yōu)化的免費(fèi)副作用。
此外,頁差錯(cuò)和TLB丟失的成本通常比L2高速緩存丟失的成本高得多。因此頁優(yōu)化的潛在節(jié)約要比高速緩存優(yōu)化的潛在節(jié)約大得多。當(dāng)然,這是兩方面的——冷頁上有一個(gè)單獨(dú)的熱對象就可能使該頁被錯(cuò)誤地調(diào)入,并因此勾銷了優(yōu)化的絕大多數(shù)利益。因此,確保對熱數(shù)據(jù)組有好的覆蓋可能是有用的。
在某些情形中,通常以物理存儲器地址,而不是虛擬地址來索引L2高速緩存(例如,在所有X86體系結(jié)構(gòu)上都為真)。因此如果在TLB中某個(gè)頁的條目不見了,那么在L2高速緩存中有數(shù)據(jù)可能沒有多少幫助。
示例性探測模型為了增加頁密度而不是高速緩存的利用率,不需要確定數(shù)據(jù)元素兩兩間精確的時(shí)間關(guān)系。相反,在某些實(shí)施例中,僅記錄在每兩次被觸發(fā)的動(dòng)態(tài)優(yōu)化之間或在時(shí)間間隔期間被頻繁訪問的對象就足夠了。這些被訪問的對象(例如,對象、方法、過程、數(shù)據(jù)結(jié)構(gòu)等)隨即被視為熱的對象。在優(yōu)化期間,熱對象被聚集到堆某個(gè)部分中的某個(gè)頁(或某組頁)上。
在一個(gè)例子中,使用計(jì)數(shù)器來確定哪些對象是熱的。在另一個(gè)實(shí)施例中,使用編譯器(或JIT編譯器)為訪問堆數(shù)據(jù)的某些關(guān)鍵指令插入讀障礙。在一個(gè)此類例子中,讀障礙代碼可包括單個(gè)如果計(jì)數(shù)器未被設(shè)置則更新計(jì)數(shù)器的幫助例程的調(diào)用指令??捎删幾g器自動(dòng)生成寫障礙來支持世代GC,并可以修改寫障礙以插入計(jì)數(shù)器的條件更新。
在一個(gè)此類例子中,系統(tǒng)包括計(jì)數(shù)器的實(shí)現(xiàn)、讀障礙的實(shí)現(xiàn)、和對象探測(例如,對堆進(jìn)行讀/寫的操作),從而對讀和/或?qū)懹?jì)數(shù)。
可以不同方式實(shí)現(xiàn)對象引用計(jì)數(shù)器。例如,可將對象引用計(jì)數(shù)器嵌入到對象中。在另一個(gè)例子中,可將對象引用計(jì)數(shù)器實(shí)現(xiàn)為單獨(dú)的表。在另一個(gè)例子中,使用嵌入到對象中的1比特計(jì)數(shù)器。在這樣一個(gè)例子中,如果某對象被訪問,則設(shè)置一個(gè)比特來反映在某間隔期間該對象至少被訪問了一次。在另一個(gè)例子中,對應(yīng)于一個(gè)對象的若干比特可擔(dān)當(dāng)反映在間隔期間對象被訪問多少次的計(jì)數(shù)器。在一個(gè)此類例子中,每一次的訪問都被添加到對應(yīng)于被訪問對象的計(jì)數(shù)器中。訪問的閾值次數(shù)確定某對象是否為熱對象。間隔中的一次或多次訪問可用于標(biāo)識熱對象。熱對象還可包括在間隔期間初始化(創(chuàng)建)的對象。對應(yīng)于對象的一個(gè)或多個(gè)比特可存儲在對象本身中或其它地方。如果對應(yīng)于對象的計(jì)數(shù)器在對象之外,則較佳的是它位于某個(gè)可快速訪問的位置,因?yàn)橛?jì)數(shù)的額外開銷應(yīng)當(dāng)被最小化。
在另一個(gè)例子中,計(jì)數(shù)器(一個(gè)或多個(gè)比特)存儲在對象本身中。例如,CLR中每個(gè)對象有4字節(jié)的對象頭部,可用于各種目的(例如,實(shí)現(xiàn)輕量級的鎖)。在某些實(shí)施例中,可能可將這些32比特中的一個(gè)或多個(gè)比特用作計(jì)數(shù)器(或用作熱比特)。
表B是一個(gè)讀障礙代碼的例子的實(shí)例代碼。例如,可使用剖視代碼來標(biāo)記被訪問的對象。在此例中,rg是保存對象地址的寄存器,并且對象頭部從對象的開始的偏移量為-4。OBJECT_ACCESSED_BIT是用于設(shè)置對象頭部中單個(gè)比特的位掩碼。
在一個(gè)此類例子中,使用互鎖操作來設(shè)置該比特,因?yàn)閷ο箢^部可能被其它線程同時(shí)修改(例如,當(dāng)鎖定該對象時(shí))。在x86體系結(jié)構(gòu)上互鎖操作可能成本很高(例如,20-30個(gè)時(shí)鐘周期)。此外,它可能在讀操作期間弄臟一個(gè)高速緩存行,這可能會損害多處理器上的應(yīng)用程序的可測量性。因此,在另一個(gè)例子中,可用條件讀障礙來替換無條件讀障礙,即使條件讀障礙增加了讀障礙代碼的大小。在另一個(gè)例子中,為了減少所增加的代碼的大小,不將讀障礙內(nèi)聯(lián)。相反,將讀障礙代碼實(shí)現(xiàn)為幫助例程(例如,每個(gè)寄存器一個(gè))。
在另一個(gè)例子中,一種優(yōu)化算法減少讀障礙的數(shù)量,并提高了性能和/或減少額外代碼的量。在一個(gè)例子中,所用的讀障礙和常規(guī)的訪問障礙不同,因?yàn)椴辉诿總€(gè)訪問點(diǎn)都插入對它的調(diào)用。例如,可以向公用子表達(dá)式消除(CSE)優(yōu)化呈示對讀障礙代碼的調(diào)用。在另一個(gè)例子中,因?yàn)楫惓5陌l(fā)生率很低,因此不將剖視調(diào)用插入到異常處理代碼中。類似地,另一個(gè)例子忽略非內(nèi)聯(lián)的構(gòu)造函數(shù)。
此外,考慮何時(shí)復(fù)位計(jì)數(shù)器(或熱比特)是合乎需要的。在一個(gè)例子中,當(dāng)計(jì)數(shù)器嵌入到對象中時(shí),無法不掃描所有活的對象即低成本地清除計(jì)數(shù)器比特。在一個(gè)此類例子中,在無用存儲單元收集(GC)期間當(dāng)對象被遍歷時(shí),計(jì)數(shù)器被清除。在另一個(gè)例子中,在局部性目的的GC期間每次遇到熱對象即清除計(jì)數(shù)器。
在一個(gè)復(fù)制世代無用存儲單元收集的例子中,在局部性目的的GC期間清除計(jì)數(shù)器對于無用存儲單元收集發(fā)生得較頻繁且成本較低的較低世代中的對象具有不錯(cuò)的效果。因?yàn)檩^少對較高的世代進(jìn)行收集,引用比特可能隨時(shí)間過去而失去時(shí)效。因此,在一個(gè)替換例子中,較佳的是提供一種清除計(jì)數(shù)器而無需遍歷可達(dá)圖或整個(gè)堆的方法。例如,使用一種卡表(對應(yīng)于對象),它允許清除計(jì)數(shù)器,而無需依靠對可達(dá)圖或整個(gè)堆的完整遍歷。在另一個(gè)例子中,對應(yīng)于頁和/或堆的熱比特表或熱比特字段幫助減少清除計(jì)數(shù)器/比特的時(shí)間。
示例性采樣在一個(gè)例子,上述探測模型具有很低的額外開銷,并且足以加速整體性能。但是,在若干情形中,動(dòng)態(tài)堆重新組織可能不能提高改善應(yīng)用程序的性能(例如,如果數(shù)據(jù)組小到足以適應(yīng)可用的存儲器)。對于此類應(yīng)用程序,經(jīng)探測代碼(例如,讀障礙)的成本可能過高(在某些情形中使應(yīng)用程序退化多達(dá)40%)。
為了進(jìn)一步減少探測的額外開銷,一個(gè)例子只間歇地剖視代碼。例如,如果對某方法用剖視讀障礙進(jìn)行探測,那么可生成不具有探測的該方法的第二副本。在剖視期間(即,監(jiān)視、采樣、等等)使用經(jīng)探測的版本。在常規(guī)操作期間,使用不包含探測的方法。每個(gè)方法的序言進(jìn)程被擴(kuò)展成對該方法的經(jīng)探測或未經(jīng)探測的版本進(jìn)行檢查和轉(zhuǎn)移控制。在某些實(shí)施例中,后邊不作修改。出乎意料的是,此簡化可能不會減少此方法的效力(例如,在以下基準(zhǔn)上——除了某些具有長期運(yùn)行的熱循環(huán)的合成方法)。作為進(jìn)一步的優(yōu)化,可將兩個(gè)副本放在兩個(gè)單獨(dú)的代碼堆中。
有若干因素可供改變以控制采樣。例如,使用經(jīng)探測版本代碼的頻率,一旦采樣開始則使用經(jīng)探測版本多長時(shí)間。通過調(diào)整這兩個(gè)參數(shù),可以以合理的低剖視額外開銷獲得有用的剖視信息。
在一個(gè)例子中,正常運(yùn)行常規(guī)版本的代碼,并短時(shí)間地、且僅周期性地運(yùn)行經(jīng)探測版本的代碼。例如,每一萬毫秒運(yùn)行經(jīng)探測代碼10毫秒。這將產(chǎn)生關(guān)于在周期性采樣期間哪些對象被訪問的信息。此信息用于組裝熱頁。
示例性的堆重新組織CLR GC實(shí)現(xiàn)世代標(biāo)記-壓縮無用存儲單元收集器的一個(gè)變體,并將小對象堆分成三個(gè)世代。在一個(gè)例子中,可將局部性目的的堆重新組織限于大于0的世代。在世代0的收集期間不進(jìn)行堆重新組織的一個(gè)原因是那些世代0的對象中大多數(shù)是最近才分配的。因?yàn)樗鼈冏罱疟环峙洌鼈円呀?jīng)在高速緩存中或工作集中,因此不太可能從局部性改善獲取很多利益。在一個(gè)實(shí)施例中,在GC期間,系統(tǒng)標(biāo)識所有a)從前一次局部性收集起被標(biāo)記為熱對象的和b)屬于等于或低于目前正在被收集的世代的某個(gè)世代的對象。在此例中,僅這些對象是局部性優(yōu)化的候選。在所有這些候選對象被標(biāo)識之后,局部性優(yōu)化可決定要如何對其布局,以及應(yīng)將熱對象放回GC堆上的什么位置。
在一個(gè)例子中,用兩個(gè)復(fù)制階段來完成熱對象的布局。首先,根據(jù)分層結(jié)構(gòu)的分解次序,將熱對象從堆復(fù)制到臨時(shí)緩沖中(例如,如果某個(gè)熱對象包含指向其它熱對象的指針,則這些熱對象被集合到一起),從而可隨頁局部性利益獲得某些高速緩存局部性的利益,而無另外的額外開銷。初始位置被標(biāo)記成空閑并由收集器回收。第二,隨即可將重新排列好的熱對象的集合放回堆較新的一端。在另一個(gè)例子中,避免了雙重復(fù)制(例如,通過保留堆的一個(gè)指定部分)。在另一個(gè)例子中,布局機(jī)制不將來自不同世代的對象混合到一起。
將熱對象的集合方在堆較新的一端有若干潛在的好處。例如,那里很可能有足夠空間來容納熱對象的集合。此外,較佳的是不對對象作附加的提升,因?yàn)槭占^舊世代比收集較新世代的成本高。最后,某些活得較長的對象往往一被重復(fù)使用之后就死去,降級可加速對這些對象所占空間的回收。取決于實(shí)施例,將許多對象降級可能不好。但是,仍可能選擇性地對熱對象(它們包括堆的一小部分)進(jìn)行降級。此外,重要的是不要?jiǎng)?chuàng)建過多的交叉世代的指針。
示例性優(yōu)化觸發(fā)策略另一項(xiàng)考慮是判定何時(shí)觸發(fā)局部性目的的優(yōu)化。此外,判定何時(shí)觸發(fā)局部性目的不起作用,從而當(dāng)它的凈性能利益降低時(shí)不再徒勞地繼續(xù)。
有若干種用于判定何時(shí)觸發(fā)局部性目的的優(yōu)化的可能性或組合。在一個(gè)例子中,監(jiān)視硬件性能計(jì)數(shù)器以判定DTLB和L2高速緩存的缺失率。在缺失率升高時(shí),觸發(fā)局部性目的的優(yōu)化。
在另一個(gè)例子中,監(jiān)視存儲器受壓的GC收集率。在這樣一個(gè)例子中,每第二、第三、……第N次存儲器觸發(fā)的收集時(shí)進(jìn)行熱對象局部性優(yōu)化。在某些例子中,對每次存儲器壓力觸發(fā)的GC進(jìn)行局部性優(yōu)化是有利的。
在另一個(gè)例子中,監(jiān)視對象分配率。當(dāng)新對象的分配顯著降低時(shí),即假設(shè)該應(yīng)用程序在重復(fù)使用,而不是分配新的對象。一旦分配率降低并變得相對穩(wěn)定,即觸發(fā)局部性目的的優(yōu)化。
在另一個(gè)例子中,查看對象中的引用計(jì)數(shù)是有利的。對象很高的引用計(jì)數(shù)指示同樣對象被再三訪問,優(yōu)化可能證實(shí)為有利。但是,如果引用計(jì)數(shù)很低,那么優(yōu)化不太可能證實(shí)為有利,因?yàn)樘幚砥鞑]有再三請求同樣的對象。
在另一個(gè)例子中,同時(shí)監(jiān)視分配率和性能計(jì)數(shù)器。當(dāng)分配率增長并且很高時(shí),不進(jìn)行優(yōu)化。但是一旦分配率下降并趨于相對穩(wěn)定,該程序的數(shù)據(jù)結(jié)構(gòu)很可能已建立起來,并且更可能的是對象會被重復(fù)訪問,創(chuàng)造了收益于局部性優(yōu)化的機(jī)會。此外,一旦分配率較低且相對穩(wěn)定,如性能計(jì)數(shù)器所指示的DTLB或L2高速緩存的高缺失率很可能提供很好的優(yōu)化觸發(fā)。因?yàn)樾路峙浜苌?,DTLB和L2高速緩存的丟失指示區(qū)塊被快速地調(diào)入和調(diào)出RAM和高速緩存,集合熱對象很可能會減少整體的DTLB和L2的丟失。
在另一個(gè)例子中,可在規(guī)則或可變的時(shí)間間隔觸發(fā)數(shù)據(jù)局部性目的的優(yōu)化。在另一個(gè)例子中,如果前一次的優(yōu)化顯示很低的性能提高(例如,優(yōu)化后有同樣的DTLB缺失率,等等)且每兩次優(yōu)化之間的時(shí)間間隔過小,則可增加下一次優(yōu)化之前的時(shí)間間隔。如果前一次優(yōu)化對DTLB缺失率的改善超過某個(gè)閾值并且時(shí)間間隔過大,則可提早觸發(fā)下一次優(yōu)化。
這些試探的組合也是可能的。性能計(jì)數(shù)器方法的一個(gè)缺點(diǎn)是通常它們不被虛擬化為過程(即,它們進(jìn)行全局計(jì)數(shù)),因此數(shù)字可能被系統(tǒng)上運(yùn)行的其它應(yīng)用程序歪曲。但是,它們在某些芯片上的確具有無額外成本的優(yōu)點(diǎn)。它們隨處理過程并行計(jì)數(shù)。在某些實(shí)施例中,分配率可能是觸發(fā)局部性優(yōu)化相當(dāng)可靠的度量。
在一個(gè)例子中,監(jiān)視執(zhí)行優(yōu)化的效益是有利的。例如,性能計(jì)數(shù)器用于測量一次優(yōu)化之后數(shù)據(jù)TLB和L2高速緩存的缺失率。如果根據(jù)某些相對基線,數(shù)據(jù)TLB或高速緩存的缺失率沒有改善,在某段時(shí)間停止或減少觸發(fā)局部性目的的GC或直至結(jié)果顯示效益證實(shí)成本合理,可能是合乎需要的。
因此,直接或間接觸發(fā)堆的重新組織以群集被訪問的對象的任何事物都被視作程序行為。當(dāng)受監(jiān)視的程序行為作出指示,堆即被重新組織(例如,群集)。一個(gè)或多個(gè)受監(jiān)視程序行為指示器可觸發(fā)活的熱對象的堆重新組織。
示例性提高的GC率許多關(guān)于為存儲器壓力觸發(fā)GC的文獻(xiàn)集中于因GC收集的高成本而減少GC收集的數(shù)量。相反,所描述的方法和系統(tǒng)指示,當(dāng)更多的GC收集在受局部性優(yōu)化提高時(shí),甚至在GC收集的數(shù)量增長時(shí),仍可提高總體性能。在一個(gè)例子(如下述的Xaml分析程序測試(XamlParserTest))中,GC收集增長了多達(dá)50%,而總體性能仍得以提高。
示例性性能計(jì)數(shù)器某些處理器提供各種版本的性能計(jì)數(shù)器。在一個(gè)例子中,性能計(jì)數(shù)器提供一種判定哪些對象被訪問的方法(例如,IA64處理器)。在此例中,可能不需要探測代碼。性能計(jì)數(shù)器指示在周期內(nèi)或從計(jì)數(shù)器被復(fù)位開始,哪些對象(例如,堆中的地址)被訪問。這將是有利的,因?yàn)椴恍枰綔y訪問堆的操作來標(biāo)識熱對象。例如,可經(jīng)由此測試提供TLB丟失地址。
此外,傳聞即將引入無論存儲器中的對象何時(shí)被訪問(例如,讀/寫)都作記錄的指令。這些地址或?qū)ο髮⒈挥涗浀侥硞€(gè)內(nèi)部循環(huán)緩沖器并可供使用。
這些被訪問的對象提供創(chuàng)建熱頁所需的信息。
示例性群集被分配的對象是“活的”,但僅最近被訪問的活對象還是“熱的”。以往在進(jìn)行無用存儲單元收集時(shí),熱對象是未知或不被考慮的。在無用存儲單元收集期間,活的對象被壓縮而死的對象(例如,解除分配或釋放的對象)被收集以提供新的空閑空間。使用所述技術(shù),即使沒有要求進(jìn)行無用存儲單元收集,活的熱對象在堆上也被群集起來。有趣的是,不是所有被訪問的對象需要被放在堆的同一區(qū)域才能使此技術(shù)提供充分的利益。例如,如果使用采樣周期來監(jiān)視被訪問的對象并設(shè)置訪問比特,那么僅在采樣周期內(nèi)被訪問的對象將被放置在堆上的某個(gè)熱群集中。因此,堆上的一個(gè)或多個(gè)群集并非需要包括所有最近被訪問的對象才能落入此技術(shù)的范圍之內(nèi)。此外,即使當(dāng)對象訪問監(jiān)視是連續(xù)的(相對于周期性采樣的周期,或其它),不是所有被訪問的對象都需要被放置到同一個(gè)群集才能從所述技術(shù)獲得顯著的利益。例如,如果在堆中的任何位置創(chuàng)建兩個(gè)群集,那么讓熱對象在這兩個(gè)(或甚至數(shù)個(gè)位置)而不是遍及堆的所有頁將提供顯著的利益。因此,構(gòu)想了將堆上的活的熱對象群集到一個(gè)或多個(gè)熱活對象顯著比較高度集中的位置。當(dāng)然,如果將熱對象放置到鄰近的單個(gè)群集中,這很可能提供甚至更佳的結(jié)果。例如,適應(yīng)到堆的一個(gè)頁內(nèi)的群集可能被視作理想的,但肯定不是必需的。在另一個(gè)例子中,如果熱對象的工作集大到足以占據(jù)堆上的多個(gè)頁,那么如果將那多個(gè)頁相互靠近地放置可能是有利的,但不是必需的。在另一個(gè)例子中,如果高速緩存大到足以接收一個(gè)群集的熱對象,這是有幫助的。在這樣一個(gè)例子中,如果熱對象的工作集占據(jù)多個(gè)群集,那么無論何時(shí)將這些群集中的一個(gè)調(diào)入到高速緩存中,就存在該群集中的其它熱對象即將被訪問的概率。此外,將較高概率的群集交換入或交換出高速緩存很可能需要很少的交換次數(shù),無論每個(gè)單獨(dú)的熱群集包含在堆上的何處。所有這些想法構(gòu)想了群集最近被訪問的對象。最后,在最近被分配的對象附近進(jìn)行群集提供了額外的益處。例如,在世代無用存儲單元收集堆中,在堆的最新一代附近進(jìn)行群集是有幫助的,因?yàn)樽罱环峙涞膶ο笠话阋脖容^舊對象要更熱。
示例性基準(zhǔn)在一個(gè)例子中,觀察了實(shí)驗(yàn)結(jié)果。某個(gè)原型觸發(fā)了熱對象的GC堆重新組織,并且重新組織在性能中提供有利的結(jié)果。所用的原型是Windows XP操作系統(tǒng)上共發(fā)GC無效的商業(yè)CLR實(shí)現(xiàn)的工作站版本。實(shí)驗(yàn)是在若干個(gè)具有不同存儲器、高速緩存大小和CPU速度的配置的機(jī)器上進(jìn)行的。局部性目的的GC在具有較小L2高速緩存和存儲器的機(jī)器上性能提高最多,這毫不出人意料。
創(chuàng)建了4個(gè)微基準(zhǔn),并獲得兩個(gè)用C#編寫的應(yīng)用程序以供分析使用。編寫這4個(gè)微基準(zhǔn)(即,樹、數(shù)組、S列表和散列表)用來測試局部性目的的GC的性能提高。微基準(zhǔn)從與一些垃圾數(shù)據(jù)交錯(cuò)的大量隨機(jī)創(chuàng)建的數(shù)據(jù)創(chuàng)造各自的數(shù)據(jù)結(jié)構(gòu)。在一個(gè)訓(xùn)練循環(huán)和一次強(qiáng)迫的GC之后,各個(gè)基準(zhǔn)重復(fù)地搜索一組數(shù)據(jù)。一個(gè)稱作“Xaml分析程序測試”的測試應(yīng)用程序從某個(gè)XAML文件讀三次以測算分析程序不同組件的性能。XAML(可擴(kuò)展應(yīng)用程序標(biāo)記語言)是基于XML的。所用的輸入文件包含單個(gè)但有11000級深度嵌套的節(jié)點(diǎn)。另一個(gè)稱為“SAT求解程序”的應(yīng)用程序是從其C++實(shí)現(xiàn)轉(zhuǎn)換成C#的SAT分析程序。該輸入文件描述了一個(gè)具有246403250個(gè)可變CNF(合取范式)的問題實(shí)例。
示例性性能結(jié)果各個(gè)基準(zhǔn)的執(zhí)行時(shí)間在表C中示出。對于所創(chuàng)建的全部4個(gè)微基準(zhǔn),優(yōu)化獲得如所預(yù)期的效果。但是,對于所獲得的兩個(gè)基準(zhǔn),局部性目的GC的性能充分地改善了Xaml分析程序測試,但僅稍微改善了SAT求解程序。性能利益在指針密集的應(yīng)用程序中降低了。在這樣一個(gè)例子中,甚至還沒有進(jìn)行優(yōu)化(即,在GC期間監(jiān)視和重新組織熱對象),無用存儲單元收集本身的額外開銷已經(jīng)過高,占執(zhí)行時(shí)間大約六分之一到三分之一。
示例性剖視額外開銷探測的額外開銷可能根據(jù)是采取常開方式還是采樣方式而改變。表D在常開和采樣方式間比較剖視額外開銷。采樣使得剖視的額外開銷對于優(yōu)化來說是可接受的。
示例性頁密度提高表E指示優(yōu)化(即,觸發(fā)GC將熱對象重新組織到一個(gè)或多個(gè)頁上)前后每個(gè)時(shí)間間隔被訪問的頁的平均數(shù)量和平均頁密度。測算過程是收集存儲器引用的軌跡、將執(zhí)行分成1000000個(gè)引用間隔(對于散列表微基準(zhǔn),每個(gè)間隔包含10000000個(gè)引用),并計(jì)算每個(gè)間隔被訪問的頁數(shù)及最后1000個(gè)間隔每個(gè)頁上實(shí)際被訪問的數(shù)據(jù)的百分比。一般而言,通過根據(jù)程序的訪問模式組合對象,優(yōu)化可減少工作集并可增加每頁上的“有用”數(shù)據(jù)。對于SAT求解器,每個(gè)間隔被訪問的頁數(shù)隨優(yōu)化增長,因?yàn)閮?yōu)化涉及多得多的GC,每次GC都掃描堆的局部或整體,并且沒有將無用存儲單元收集器進(jìn)行的訪問排除在計(jì)算之外。
示例性局部性改善為了驗(yàn)證優(yōu)化在工作集和頁密度上的改善,還收集了關(guān)于DTLB丟失數(shù)量的數(shù)據(jù),如表F中所示。作為工作集和頁密度改善的結(jié)果,優(yōu)化還減少了DTLB丟失的數(shù)量。表F中還示出基準(zhǔn)的L2高速緩存丟失數(shù)量。盡管優(yōu)化不集中于高速緩存局部性,它在改善高速緩存局部性中有良好的效果。
示例性計(jì)算環(huán)境圖8和以下討論旨在提供實(shí)現(xiàn)的合適計(jì)算環(huán)境的簡要、概括的描述。盡管將在計(jì)算機(jī)和/或網(wǎng)絡(luò)設(shè)備上運(yùn)行的計(jì)算機(jī)程序的計(jì)算機(jī)可執(zhí)行指令的通用上下文中描述本發(fā)明,本領(lǐng)域技術(shù)人員將意識到還可結(jié)合其它程序模塊實(shí)現(xiàn)本發(fā)明。一般而言,程序模塊包括執(zhí)行特定任務(wù)或?qū)嵤┨囟ǔ橄髷?shù)據(jù)類型的例程、程序、組件、數(shù)據(jù)結(jié)構(gòu)等等。此外,本領(lǐng)域技術(shù)人員應(yīng)理解可隨其它計(jì)算機(jī)系統(tǒng)配置實(shí)施本發(fā)明,包括微處理器系統(tǒng)、基于微處理器的電子設(shè)備、微型計(jì)算機(jī)、大型計(jì)算機(jī)、網(wǎng)絡(luò)裝置、無線設(shè)備、等等??梢栽诼?lián)網(wǎng)計(jì)算環(huán)境中,或在獨(dú)立計(jì)算機(jī)上實(shí)施各種擴(kuò)展。
參考圖8,用于實(shí)現(xiàn)的示例性系統(tǒng)包括常規(guī)計(jì)算機(jī)820(諸如個(gè)人計(jì)算機(jī)、膝上計(jì)算機(jī)、服務(wù)器、大型計(jì)算機(jī)、和其它種種計(jì)算機(jī)),該計(jì)算機(jī)包括處理單元821、系統(tǒng)存儲器822、和將包括系統(tǒng)存儲器在內(nèi)的各種系統(tǒng)組件耦合到處理單元821的系統(tǒng)總線823。處理單元可以是各種商業(yè)上可用的處理器中的任何一種,包括Intel x86、Pentium和來自Intel及其它公司的兼容微處理器,這些兼容微處理器包括Cyrix、AMD和Nexgen;來自Digital的Alpha;來自MIPS科技、NEC、IDT、Siemens及其它公司的MIPS;來自Sun及其它公司的SPARC;和來自IBM和Motorola的PowerPC。雙微處理器及其它多處理器體系結(jié)構(gòu)也可用作處理單元821。
系統(tǒng)總線可以是若干種總線結(jié)構(gòu)中的任何一種,包括存儲器總線或存儲器控制器、外圍總線、和使用各種可用的總線體系結(jié)構(gòu)中的任一種的局部總線,僅舉幾個(gè)例子,這些體系結(jié)構(gòu)包括PCI、VESA、AGP、微通道、ISA和EISA。系統(tǒng)存儲器包括只讀存儲器(ROM)824和隨機(jī)存取存儲器(RAM)825。包含諸如在啟動(dòng)時(shí)幫助在計(jì)算機(jī)820內(nèi)部各元件間傳遞信息的基本例程的基本輸入/輸出系統(tǒng)(BIOS)儲存在非易失性存儲器ROM 824中。
計(jì)算機(jī)820還包括硬盤驅(qū)動(dòng)器827、例如讀寫可移動(dòng)磁盤829的磁盤驅(qū)動(dòng)器828、和例如讀CD-ROM盤831或讀寫其它光介質(zhì)的光盤驅(qū)動(dòng)器830。硬盤驅(qū)動(dòng)器827、磁盤驅(qū)動(dòng)器828、和光盤驅(qū)動(dòng)器830分別由硬盤驅(qū)動(dòng)器接口832、磁盤驅(qū)動(dòng)器接口833和光盤驅(qū)動(dòng)器接口834連接到系統(tǒng)總線823。各個(gè)驅(qū)動(dòng)器及其相關(guān)聯(lián)的計(jì)算機(jī)可讀介質(zhì)為計(jì)算機(jī)820提供數(shù)據(jù)、數(shù)據(jù)結(jié)構(gòu)、計(jì)算機(jī)可執(zhí)行指令等的非易失性的存儲。盡管以上對計(jì)算機(jī)可讀介質(zhì)的描述指硬盤、可移動(dòng)磁盤和CD,本領(lǐng)域技術(shù)人員應(yīng)當(dāng)理解,諸如磁帶盒、閃存卡、數(shù)字視頻盤、貝努利盒式磁帶等其它類型的計(jì)算機(jī)可讀介質(zhì)也可在示例性操作環(huán)境中使用。
若干程序模塊可存儲在各個(gè)驅(qū)動(dòng)器和RAM 825中,除了所描述的監(jiān)視和優(yōu)化的實(shí)現(xiàn)856以外,還包括操作系統(tǒng)835、一個(gè)或多個(gè)應(yīng)用程序836、其它程序模塊837、和程序數(shù)據(jù)838。
用戶可通過鍵盤840和諸如鼠標(biāo)842等定位設(shè)備將命令和信息輸入到計(jì)算機(jī)820中。這些及其它輸入設(shè)備常通過耦合到系統(tǒng)總線的串行端口接口846連接到處理單元821,但也可通過其它接口連接,諸如并行端口、游戲端口或通用串行總線(USB)。監(jiān)視器847或其它類型的顯示設(shè)備也經(jīng)由諸如視頻適配器848等接口連接到系統(tǒng)總線823。除了監(jiān)視器以外,計(jì)算機(jī)通常包括其它外圍輸出設(shè)備(未圖示),諸如揚(yáng)聲器和打印機(jī)。
計(jì)算機(jī)820使用到諸如遠(yuǎn)程計(jì)算機(jī)849等一個(gè)或多個(gè)遠(yuǎn)程計(jì)算機(jī)的邏輯連接,在聯(lián)網(wǎng)環(huán)境中操作。遠(yuǎn)程計(jì)算機(jī)849可以是服務(wù)器、路由器、對等設(shè)備或其它公用網(wǎng)絡(luò)節(jié)點(diǎn),并通常包括以上相對于計(jì)算機(jī)820所描述的許多或全部元件,盡管圖中僅示出記憶存儲設(shè)備850。圖示的邏輯連接包括局域網(wǎng)(LAN)851和廣域網(wǎng)852。此類聯(lián)網(wǎng)環(huán)境常見于辦公室、企業(yè)范圍的計(jì)算機(jī)網(wǎng)絡(luò)、內(nèi)聯(lián)網(wǎng)和因特網(wǎng)。
當(dāng)在LAN網(wǎng)絡(luò)環(huán)境中使用時(shí),計(jì)算機(jī)820通過網(wǎng)絡(luò)接口或適配器853連接到本地網(wǎng)絡(luò)851。當(dāng)在WAN網(wǎng)絡(luò)環(huán)境中使用時(shí),計(jì)算機(jī)820通常包括調(diào)制解調(diào)器854或其它手段,用于通過諸如因特網(wǎng)等廣域網(wǎng)852建立通信(例如,經(jīng)由LAN 851和網(wǎng)關(guān)或代理服務(wù)器855)??梢允莾?nèi)置或外置的調(diào)制解調(diào)器854經(jīng)由串行端口接口846連接到系統(tǒng)總線823。在聯(lián)網(wǎng)環(huán)境中,相對于計(jì)算機(jī)820所描述的程序模塊或其部分可存儲在遠(yuǎn)程記憶存儲設(shè)備中??梢岳斫?,所示網(wǎng)絡(luò)連接是示例性的,可以使用其它在計(jì)算設(shè)備兩兩間建立通信鏈路的手段,無論是無線還是有線的。
替換方案以上參考各個(gè)示出的例子描述并說明了我們的發(fā)明的原理,可以意識到,可以在安排和細(xì)節(jié)上修改這些例子,而不會偏離此類原理。此外,如對于普通計(jì)算機(jī)科學(xué)家來說顯而易見的,部分例子或所有例子可完整或局部地與其它例子的其它部分結(jié)合。應(yīng)當(dāng)理解,本文中所描述的程序、過程、或方法并不涉及或限于任何特定類型的計(jì)算機(jī)設(shè)備,除非另外指出。根據(jù)本文中所描述的教義,各種類型的通用或?qū)S糜?jì)算機(jī)設(shè)備可配合各種操作使用,或可用于進(jìn)行各種操作。以軟件形式表現(xiàn)的所示實(shí)施例的元素可以硬件實(shí)現(xiàn),反之亦然。來自一個(gè)例子的技術(shù)可合并到任何其它例子中。
考慮到可引用我們的發(fā)明的原理的許多可能的實(shí)施例,應(yīng)當(dāng)意識到各個(gè)細(xì)節(jié)只是說明性的,并且不應(yīng)被視作限制我們的發(fā)明的范圍。相反,我們要求將所有此類可能落入所附權(quán)利要求書及其等效技術(shù)方案的范圍和精神的實(shí)施例作為我們的發(fā)明。
權(quán)利要求
1.一種計(jì)算機(jī)化的方法,其特征在于,包括監(jiān)視一執(zhí)行程序以確定最近被訪問的對象;操縱至少一個(gè)比特以指示一對象訪問;監(jiān)視一程序行為指示器;基于所監(jiān)視的程序行為指示器調(diào)用優(yōu)化;以及執(zhí)行所述優(yōu)化,包括將所訪問的對象群集到存儲器中,以及為每個(gè)所訪問的對象復(fù)位所操縱的至少一個(gè)比特。
2.如權(quán)利要求1所述的方法,其特征在于,所述至少一個(gè)比特是一多比特計(jì)數(shù)器,并且所述操縱使所述多比特計(jì)數(shù)器遞增。
3.如權(quán)利要求1所述的方法,其特征在于,所群集的被訪問對象位于用世代無用存儲單元收集的堆的較新的一端。
4.如權(quán)利要求1所述的方法,其特征在于,它是由虛擬機(jī)進(jìn)行的。
5.如權(quán)利要求1所述的方法,其特征在于,所述至少一個(gè)比特位于所訪問對象的頭部。
6.如權(quán)利要求1所述的方法,其特征在于,所述至少一個(gè)比特位于所訪問對象以外。
7.如權(quán)利要求1所述的方法,其特征在于,所訪問對象是以如下次序來集合的如果第一個(gè)被訪問對象包含指向第二個(gè)被訪問對象的指針,那么在一群集內(nèi)將所述第一和第二個(gè)對象組合在一起。
8.如權(quán)利要求1所述的方法,其特征在于,所群集的被訪問對象包括堆存儲器的一個(gè)或多個(gè)頁。
9.如權(quán)利要求1所述的方法,其特征在于,所群集的被訪問對象包括堆存儲器的多個(gè)連續(xù)的頁。
10.如權(quán)利要求1所述的方法,其特征在于,所群集的對象包括位于所述堆的不鄰近區(qū)域中的被訪問對象的多個(gè)單獨(dú)群集。
11.如權(quán)利要求1所述的方法,其特征在于,程序行為指示器是一性能計(jì)數(shù)器。
12.如權(quán)利要求1所述的方法,其特征在于,程序行為指示器是第N次存儲器壓力無用存儲單元收集。
13.如權(quán)利要求1所述的方法,其特征在于,程序行為指示器是分配率。
14.如權(quán)利要求1所述的方法,其特征在于,程序行為指示器是對象引用計(jì)數(shù)器。
15.如權(quán)利要求1所述的方法,其特征在于,程序行為指示器是多個(gè)行為指示器的編譯。
16.如權(quán)利要求1所述的方法,其特征在于,所述方法監(jiān)視兩個(gè)或多個(gè)程序行為指示器。
17.一種計(jì)算機(jī)系統(tǒng),其特征在于,包含存儲器和執(zhí)行被監(jiān)視程序的中央處理單元;以及用于監(jiān)視和優(yōu)化所述被監(jiān)視程序的優(yōu)化模塊,并且包含,用于探測所述程序以在程序執(zhí)行期間記錄對象訪問的探測模塊,用于監(jiān)視程序行為并響應(yīng)于被監(jiān)視程序行為調(diào)用優(yōu)化的優(yōu)化模塊,所述優(yōu)化包括在存儲器中群集最近記錄的被訪問對象。
18.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,所述受監(jiān)視程序行為是DTLB高速緩存缺失率。
19.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,所述受監(jiān)視程序行為是L2高速緩存缺失率。
20.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,所述受監(jiān)視程序行為是分配率。
21.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,所述優(yōu)化模塊是復(fù)制世代無用存儲單元收集模塊的一部分。
22.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,所述探測模塊包括JIT編譯器。
23.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,所記錄的對象訪問包括設(shè)置對應(yīng)于一被訪問對象的一個(gè)比特。
24.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,所述優(yōu)化模塊還包括遍歷堆上的對象并經(jīng)由所述對象中設(shè)置的比特來標(biāo)識哪些對象最近被訪問。
25.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,指向另一個(gè)最近被訪問對象的一個(gè)最近被訪問對象被放在靠近該對象的地方。
26.如權(quán)利要求17所述的計(jì)算機(jī)系統(tǒng),其特征在于,所述優(yōu)化還包括判定所群集的最近記錄的被訪問對象占據(jù)比單個(gè)堆頁所持有的更多的存儲器更,因而過剩的最近被訪問的對象被流到第二堆頁的群集中。
27.如權(quán)利要求26所述的計(jì)算機(jī)系統(tǒng),其特征在于,經(jīng)探測的程序在對應(yīng)于堆地址的一個(gè)位矢量中記錄對象訪問。
28.一種其上具有計(jì)算機(jī)可讀指令的計(jì)算機(jī)可讀介質(zhì),其特征在于,所述計(jì)算機(jī)指令包括用于探測應(yīng)用程序以記錄對象訪問的指令;用于監(jiān)視所述應(yīng)用程序的行為的指令;用于基于所述應(yīng)用程序的受監(jiān)視的行為調(diào)用堆優(yōu)化的指令;以及所述堆優(yōu)化包括用于在所述堆上將最近被訪問的對象復(fù)制到彼此靠近的位置的指令。
29.如權(quán)利要求28所述的計(jì)算機(jī)可讀介質(zhì),其特征在于,還包括用于探測對象以對其在堆優(yōu)化之間被訪問多少次數(shù)進(jìn)行計(jì)數(shù)的指令。
30.如權(quán)利要求28所述的計(jì)算機(jī)可讀介質(zhì),其特征在于,還包括用于探測對象以當(dāng)所述對象中的數(shù)據(jù)字段被訪問時(shí)設(shè)置其頭部內(nèi)的一個(gè)比特的指令。
31.一種用于為應(yīng)用程序改善數(shù)據(jù)局部性的系統(tǒng),其特征在于,所述系統(tǒng)包括即時(shí)編譯器,它被配置成取所述應(yīng)用程序一種中間語言表示,并將其編譯成用于特定體系結(jié)構(gòu)的機(jī)器代碼,其中,所述即時(shí)編譯器被配置成生成經(jīng)探測的代碼,其中,所述經(jīng)探測的代碼被配置成標(biāo)記最近被訪問的對象;監(jiān)視代碼,它被配置成在所述應(yīng)用程序運(yùn)行時(shí)收集度量,其中,所述監(jiān)視代碼被配置成監(jiān)視所標(biāo)記的對象,并觸發(fā)局部性目的的無用存儲單元收集,其中,所述局部性目的的無用存儲單元收集包括將被標(biāo)記成最近被訪問的對象布置到與所述堆的其余部分相分離的頁上。
32.如權(quán)利要求31所述的系統(tǒng),其特征在于,所述局部性目的的無用存儲單元收集是獨(dú)立于為回收空間而觸發(fā)的常規(guī)無用存儲單元收集而觸發(fā)的。
33.如權(quán)利要求31所述的系統(tǒng),其特征在于,所述經(jīng)探測的代碼被配置成通過更新嵌入到所述對象中的對象引用計(jì)數(shù)器來標(biāo)記所述對象。
34.如權(quán)利要求31所述的系統(tǒng),其特征在于,所述經(jīng)探測的代碼被配置成通過更新存儲在與所述對象相分離的表中的對象引用計(jì)數(shù)器來標(biāo)記所述對象。
35.如權(quán)利要求32所述的系統(tǒng),其特征在于,所述即時(shí)編譯器在具有訪問堆數(shù)據(jù)的關(guān)鍵指令的方法中生成剖視讀障礙。
36.如權(quán)利要求31所述的系統(tǒng),其特征在于,所述即時(shí)編譯器生成兩個(gè)版本的方法,其中,所述方法的第一個(gè)版本和所述方法的第二個(gè)版本放在分開的代碼堆中。
全文摘要
用如C#等現(xiàn)代的無用存儲單元收集語言編寫的應(yīng)用程序往往有很大的動(dòng)態(tài)工作集和很差的數(shù)據(jù)局部性,因此很可能要在管理存儲器分層結(jié)構(gòu)之間的數(shù)據(jù)移動(dòng)上花費(fèi)額外的時(shí)間。作為代替,一種低額外開銷的動(dòng)態(tài)技術(shù)改進(jìn)了應(yīng)用程序的數(shù)據(jù)局部性。此技術(shù)在程序運(yùn)行時(shí)監(jiān)視對象,并將最近訪問的各個(gè)對象放在堆上的相同的一個(gè)或數(shù)個(gè)頁上。提供增加的頁密度是減少DTLB和/或數(shù)據(jù)高速緩存丟失的有效方法。
文檔編號G06F9/44GK1838090SQ20051010401
公開日2006年9月27日 申請日期2005年9月9日 優(yōu)先權(quán)日2004年9月10日
發(fā)明者S·班薩利, W·-K·陳, X·高 申請人:微軟公司