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