一種多核并行離散事件仿真的內存管理方法
【技術領域】
[0001]本發明涉及多核并行離散事件仿真系統的內存管理方法,尤其是針對多核并行離散仿真系統的內存管理問題,提供一種基于事件包全局虛擬時間估計的邏輯進程循環內存分配與回收管理方法。
【背景技術】
[0002]并行離散事件仿真(ParallelDiscrete Event Simulat1n, PDES)由一組邏輯進程(Logical Process,LP)構成,每個LP有獨立的狀態,負責自身的模型解算,并且有自己獨立的仿真邏輯時間,稱為本地虛擬時間(Local Virtual Time,LVT)。并行離散事件仿真系統的LP是并行運行的。LP之間不共享任何的狀態變量,僅通過發送和接收事件的方式進行數據傳遞。
[0003]一般地,多核并行離散事件仿真系統是指在一個或多個CPU上運行的并行離散時間仿真系統,其最主要特征是每個邏輯進程關聯到一個CPU物理核,整個仿真系統的程序在一個進程空間內,邏輯進程不需要跨進程通信。多核并行離散事件仿真系統和分布式并行離散事件仿真系統相比,最大優勢是邏輯進程間的通信開銷小、運行效率高。但由于操作系統的全局統一分配內存需要同步,因此,需要對多核并行離散事件仿真系統使用的內存進行管理。多核并行離散事件仿真系統的內存管理過程包括內存分配、全局虛擬時間(Global Virtual Time, GVT)估計、內存回收三個步驟。
[0004]首先,多個邏輯進程在創建事件時需要同時向操作系統申請內存空間,邏輯進程申請內存的操作容易成為仿真系統運行性能的瓶頸。需要有合適的內存分配方式來解決多個邏輯進程申請內存的競爭問題。
[0005]其次,并行離散事件仿真系統的每個事件都有一個時戳(timestamp),時戳表示事件發生的仿真邏輯時間。為了確保仿真因果關系,每個LP必須按照事件時戳的增序關系順序處理事件,否則仿真系統將出現因果錯誤(causality errors)。因此,這樣的并行執行機制和因果關系要求,使得并行離散事件仿真必須引入時間同步機制協調LP的運行。當前,同步機制主要有保守時間同步算法和樂觀時間同步算法。保守時間同步算法能夠嚴格的防止出現因果錯誤,但會阻塞LP的運行,使得LP的并行性較差。樂觀時間同步算法,也稱為時間彎曲(Time Wrap)算法,則不阻塞LP的運行,允許因果錯誤出現。在樂觀時間同步機制下,已處理的事件占用的內存空間不能被邏輯進程立刻回收。邏輯進程將已處理的事件保存起來,當檢測到出現因果錯誤時,通過回滾(rollback)的方式將邏輯進程的狀態恢復到之前正常的狀態,然后重新按照事件的時序關系繼續執行。只有時戳小于全局虛擬時間(Global Virtual Time, GVT)的事件才不會被回滾,其占用的內存空間才可以被安全的回收。全局虛擬時間估計算法的效率和精度直接影響仿真系統內存使用的效率。
[0006]最后,內存的回收方式也會影響內存的使用效率。例如,全局內存池雖然可以解決內存分配競爭的問題,但是內存回收和內存分配還是需要同步操作。
[0007]因此,多核并行離散事件仿真系統的內存管理與內存分配方式、全局虛擬時間估計的精度、內存回收方式相關。仿真系統的內存管理直接影響了仿真系統的運行效率,已經成為仿真領域研宄人員關心的一個關鍵技術問題。很多研宄人員在這方面做了很多研宄工作,例如全局內存池方法、基于線程的內存池方法等。這些方法可以部分解決內存分配競爭的問題,但是沒有和全局虛擬時間的估計相結合,沒有完全解決內存是否可回收以及回收方式的問題。
【發明內容】
[0008]本發明要解決的技術問題是:提供一種多核并行離散事件仿真的內存管理方法,滿足仿真實驗過程中多個邏輯進程同時申請內存空間的要求,避免內存申請同步操作。通過準確估計全局虛擬時間GVT,快速、精確回收事件占用的內存,提高內存的使用效率。
[0009]本方法由N個邏輯進程和一個GVT計算進程實現,其中N為自然數且滿足N多2。邏輯進程用LPi表示,下標i為邏輯進程的唯一標識,I ^ i ^ No GVT計算進程用GP (GVTProcess)表示。每個邏輯進程LPi都有一個獨立的內存池MemPool i。]^1]1?00]^是一個先入先出(FIFO)的動態隊列,隊列的大小一般取128、256、512、1024幾個典型值,隊列的每個元素是一個內存塊,在一個內存塊上,邏輯進程LPi可以創建用于與其他邏輯進程間進行數據交換的事件。事件定義為四元組BE (s, t, ebi, ts, ed),其中BE.s表示發送該事件的邏輯進程的唯一標識,BE.t表示接收該事件的邏輯進程的唯一標識;BE.ebi是事件的索引,為正整數;BE.ts是事件的仿真時戳,為正實數;BE.ed是事件攜帶的和具體應用相關的數據,為通用型指針,如void*。邏輯進程LPi有一個事件緩沖隊列EventCacheList 1、一個待處理事件隊列 UnProEventListjP—個已處理事件隊列 ProEventList iD EventCacheListi是一個線程安全的并發隊列,用于接收其他邏輯進程發來的事件。對于EventCacheListi,多個事件的插入和讀取操作可以并行進行。UnPr0EventListi用于存放邏輯進程LP i的還沒有處理事件,ProEventListi用于存放邏輯進程LP ^勺已處理但還沒有回收內存的事件。
[0010]此外,所有的邏輯進程都包含以下變量,以邏輯進程1^為例:用于記錄邏輯進程LPi的事件包索引的變量ebi i,ebiiS正整數;事件包的大小EventSize p EventSizei為正整數;邏輯進程LPi自身記錄的全局虛擬時間GVTValue PGVTValueiS正實數;記錄LPi的仿真結束時間的變量StopTimei,正實數;邏輯進程LP ^勺本地虛擬時間LVT ^ LVTi為正實數;邏輯進程1^發送的事件的最小時戳MTS i,MTS^正實數;邏輯進程LP i給其他邏輯進程發送的事件的計數器SntCi, SntCiS正整數;記錄邏輯進程LP ,收到的其他進程發來的事件的計數器,稱為暫態事件計數器RcvMapi。一個大小可以動態變化的動態隊列,隊列的每個元素是一個形如(eventKey、EValue)的二元組,二元組的鍵eventKey是事件的索引,值EValue是邏輯進程LPi收到的索引為對應鍵值的事件的數量。
[0011]所有的邏輯進程通過構建自己的事件包消息向GVT計算進程GP發送估計GVT所需的數據。事件包消息定義為五元組EBR(id,ebi, LVT, MTS, TMMap),其中EBR.1d是發送該事件包消息的邏輯進程的唯一標識,若邏輯進程LPi*送事件包消息,那么EBR.1d的取值為i。EBR.ebi是事件包消息產生時對應的邏輯進程的事件包索引,若邏輯進程LPi發送事件包消息,那么EBR.ebi取值為eb1- EBR.LVT記錄邏輯進程的本地虛擬時間,EBR.MTS記錄邏輯進程發送的事件的最小時戳。EBR.TMMap稱為事件包消息的暫態事件計數器,它和邏輯進程LPi的暫態事件計數器RcvMap i有相同的數據結構。邏輯進程LP 送事件包消息時,LP^f RcvMap i的數據完全賦值給EBR.TMMap。
[0012]GVT計算進程GP通過事件包消息緩沖隊列EBRCacheList儲存所有邏輯進程發來的事件包消息。EBRCacheList是一個線程安全的并發隊列。多個邏輯進程可以并發地向一個GVT計算進程的事件包消息緩沖隊列插入多個事件包消息。此外,GP通過三個動態隊列TMCMap, MTSMap和LVTMap記錄所有邏輯進程發來的每個事件包消息的數據。其中,暫態消息隊列TMCMap是大小可以動態變化的隊列,隊列的每個元素是一個形如(ebKey、EBValue)的二元組,二元組的鍵ebKey是事件包消息的索引,值EBValue是有相同索引的事件的數量。事件最小時戳隊列MTSMap是大小可以動態變化的隊列隊列的每個元素是一個形如(ebKey、MTValue)的二元組,二元組的鍵ebKey是事件包消息的索引,值MTValue記錄事件包消息的發送事件的時戳最小值EBR.MTS ;本地虛擬時間隊列LVTMap是大小可以動態變化的隊列,隊列的每個元素是一個形如(ebKey、TValue)的二元組,二元組的鍵ebKey是事件包消息的索引,值TValue記錄事件包消息記錄的本地虛擬時間EBR.LVT。此外,GVT計算進程還包含一個GVTValue變量和一個StopTime變量。GVTValue變量用于記錄估計出的GVT時間,GVTValue是正實數;變量StopTime記錄仿真結束時間,StopTime是正實數。
[0013]GP通過計算獲得GVT的新的估計值后,通過GVT通知消息給其他邏輯進程發送GVT的值,GVT通知消息表示為GN(NewGVTValue),其中GN.NewGVTValue表示新的GVT估計值,為正實數。
[0014]本方法的基本處理過程是:首先創建N個邏輯進程和一個GVT計算進程,N個邏輯進程、GVT計算進程同時進行初始化;然后N個邏輯進程并行地處理事件、向自己的內存池申請內存、發送事件、接收事件、向GVT計算進程發送事件包消息;GVT計算進程收集到N個具有相同索引的事件包消息后計算GVT的值,然后向所有邏輯進程發送GVT通知消息;最后N個邏輯進程并行地讀取GVT通知消息并獲取GVT的值,再回收時戳小于全局虛擬時間的事件占用的內存。回收的內存放入處理事件的邏輯進程的內存池,而非內存被分配時所在的內存池。例如,邏輯進程LPi向MemPool i申請的內存,創建事件BE (i,j, ebi, ts, ed)并發給邏輯進程LPj (i Φ j),事件BE(i,j,ebi,tS,ed)占用的內存將被邏輯進程LPj的內存池MemPoolj回收。反之,邏輯進程LP」給邏輯進程LP i發送的事件BE(j, i, ebi, ts, ed)占用的內存被邏輯進程LPi的內存池MemPool i回收。這就是循環內存分配與回收方法。
[0015]具體的技術方案如下:
[0016]第一步:創建N個邏輯進程和一個GVT計算進程,GVT計算進程進行初始化,N個邏輯進程并發地進行初始化并分配內存池。1.1,1.2是兩個并行的步驟。
[0017]1.1:GVT計算進程初始化,具體步驟是:首先給StopTime賦值,如StopTime =5000。StopTime的取值和具體的應用相關,可以取任何的正實數,如5000,單位可以為秒、分鐘、小時等時間單位。然后令GVTValue = 0,GVTValue的單位和StopTime的單位相同。最后GVT計算進程轉到第四步。
[0018]1.2:N個邏輯進程并行地初始化,邏輯進程LPi進行初始化的方法是=StopTimei =StopTime,GVTValuei= O, ebi j= I, LVT j = 0,MTS j = 0,SntCi= 0, RcvMap 丨為空,EventSize j的取值為 2P 形式,P 為自然數,EventSize i—般取值為 8、16、32、64、128,EventCacheList $空,ProEventLiSti為空。邏輯進程LP i將初始事件插入待處理事件隊列UnProEventList ^初始事件的個數不小于I。N個邏輯進程執行第二步。
[0019]第二步:N個邏輯進程并行地處理事件、發送事件和接收事件。每個邏輯進程通過自己的并發事件緩沖隊列實現同時接收多個事件以及讀取事件所需的同步操作。邏輯進程1^處理事件、發送事件和接收事件的方法為:
[0020]2.1:設置邏輯進程1^的變量,MTSi= OjntCi= 0,RcvMap i為空,令已處理事件計數器PEventCoun