簡介:
系統結構實驗常用的工具是模擬器simulator。Multi2sim是多核時鐘精確模擬器,支援可變的儲存層次結構,網路連結目前只支援Bus和P2P,但是對於記憶體的模擬只是簡單返回200cycle延遲,對於研究記憶體控制器有很大的限制。DRAMsim是記憶體時鐘精確模擬器。於是本文的工作是把Multi2sim與DRAMsim相串連實現更強大的功能。
源碼:
1、Multi2sim: A CPU-GPU Model for Heterogeneous Computing
CSDN:http://download.csdn.net/detail/koala002/3857207
2、DRAMsim: DRAMSim2 is a cycle accurate model of a DRAM memory controller
CSDN:http://download.csdn.net/detail/koala002/3857463
步驟:
1、解決C++與C程式連結問題
Multi2sim與DRAMsim介面檔案:由於Automake工具族實現對*.c尾碼檔案使用CC變數編譯器,*.cpp尾碼使用CXX變數編譯器,所以更改尾碼名為.cpp
libcachesystem/cachesystem.cpp
首先在檔案開頭包含標頭檔,定義記憶體讀寫處理函數,全域定義一個記憶體執行個體指標
#ifdef MACRO_DRAM_SIM#include "../libdram/MemorySystem.h"class some_object{public: void read_complete(unsigned, uint64_t, uint64_t);void write_complete(unsigned, uint64_t, uint64_t);int add_one_and_run();};/* callback functors */void some_object::read_complete(unsigned id, uint64_t address, uint64_t clock_cycle){//esim_schedule_event(EV_MOESI_FIND_AND_LOCK_FINISH, stack, ccache->lat);//printf("[Callback] read complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle);}void some_object::write_complete(unsigned id, uint64_t address, uint64_t clock_cycle){//esim_schedule_event(EV_MOESI_FIND_AND_LOCK_FINISH, stack, ccache->lat);//printf("[Callback] write complete: %d 0x%lx cycle=%lu\n", id, address, clock_cycle);}/* FIXME: this may be broken, currently */void power_callback(double a, double b, double c, double d){printf("power callback: %0.3f, %0.3f, %0.3f, %0.3f\n",a,b,c,d);}/* init one dramsim instance */class MemorySystem* g_dramsim_memory;#endif
其次,cache_system_init是儲存層次建立函數,申請一個記憶體執行個體,並且註冊讀寫函數
#ifdef MACRO_DRAM_SIM /* new one instance */ g_dramsim_memory= new MemorySystem(0, "ini/DDR2_micron_16M_8b_x8_sg3E.ini",\ "system.ini", "/home/jyq/multi2sim-3.1.1/src/libdram", "resultsfilename", 1024*500); /* create and register our callback functions */Callback_t *read_cb = new Callback<some_object, void, unsigned, uint64_t, uint64_t>(new some_object, &some_object::read_complete);Callback_t *write_cb = new Callback<some_object, void, unsigned, uint64_t, uint64_t>(new some_object, &some_object::write_complete); g_dramsim_memory->RegisterCallbacks(read_cb, write_cb, power_callback);#endif
libcachesystem/moesi.cpp:一致性協議操作,讀寫操作
首先,標頭檔包含,並且注意代碼快兩端加入extern "C",以保證和原來代碼相容
#ifdef MACRO_DRAM_SIM#include "../libdram/MemorySystem.h"extern MemorySystem* g_dramsim_memory;#endifextern "C"{#include "cachesystem.h"
其次,moesi_find_and_lock函數是找塊函數,讀寫操作都需要此功能函數。
如果發現沒有lonet,則為最後一級緩衝,那麼像記憶體插入transaction。
#ifdef MACRO_DRAM_SIM /* create a transaction and add it */if(!ccache->lonet){Transaction tr = Transaction(stack->read?DATA_READ:DATA_WRITE,stack->addr, stack);g_dramsim_memory->addTransaction(tr);}#endif
原來代碼記憶體模擬都只是簡單返回200Cycles,所以這裡改動如果發現是非記憶體讀操作才直接加入延遲。否則等待記憶體操作返回後由讀寫完成註冊函數處理。
#ifdef MACRO_DRAM_SIM/* Access latency */if(ccache->lonet ){esim_schedule_event(EV_MOESI_FIND_AND_LOCK_FINISH, stack, ccache->lat);}#elseesim_schedule_event(EV_MOESI_FIND_AND_LOCK_FINISH, stack, ccache->lat);#endif
ibcpuarch/cpuarch.cpp
void cpu_run():實現時鐘精確模擬,其中子函數cpu_stages()實現的是每周期取指、解碼、執行、提交、寫迴流水線,所以在之後加入記憶體更新操作,這裡注意處理器與記憶體的頻率倍數。
#ifdef MACRO_DRAM_SIM
/* Dramsim stage*/ extern class MemorySystem* g_dramsim_memory; g_dramsim_memory->update();#endif
2、為了代碼最小改動,將DRAMSim編譯成動態連結程式庫,然後在連結處與Multi2sim代碼相連結即可。
3、合并代碼過程中,由於C標準允許void*指標賦給其他類型指標,但C++標註不允許,所以在改用g++編譯某些源檔案時需要在這些賦值位置強轉類型。
4、Makefile改寫可以參考automake、configure等資料。
5、本文只是基本大體改動架構,細節功能實現或者擴充功能還需要更細改寫。