系列文章 : [gem5] 從零開始的 gem5 學習筆記
從這邊開始,就可以寫一些簡單的程式碼了!
其實這一篇的內容絕大部分來自 gem5 的官方教學 learning gem5 / Creating a very simple SimObject,這邊簡單做個中文的筆記。
雖然說是中文的筆記,結果到最後還是落得中英夾雜的晶晶體,只能說我的文學造詣還是有待加強...
在這時候,我們可以開始建立一個新的 SimObject。
SimObject 在 gem5 裡是一個 C++ 與 python 間的橋樑,當我們用 C++/python 裡實作一個 SimObject 之後,就可以在 python configuration script 裡面使用。
在這個範例,我們需要新增 5 個檔案
一開始可以先把簡單的範例編譯起來, 然後運行看看會不會出現問題
git clone -b example-object https://github.com/TommyWu-fdgkhdkgh/gem5.git
cd gem5
scons build/RISCV/gem5.debug -j$(nproc)
# 開始進行模擬
./build/RISCV/gem5.debug ./configs/learning_gem5/tommy/example.py
假如一切都沒有問題的話,最後可以看到我們自己手動加的一些 log。
…
test print in the configuration file!
…
test number : 10
Hello World! From a SimObject!
…
每一個 SimObject 都需要有一個相對應的 python class。
要注意的是,python class 跟 python configuration script 不同,當我們修改 python class 的時候,是需要重新編譯的!
這個 python class 可以在 python configuration script 裡面被使用。
{ src/learning_gem5/tommy/ExampleObject.py }
from m5.params import *
from m5.SimObject import SimObject
class ExampleObject(SimObject):
type = "ExampleObject"
cxx_header = "learning_gem5/tommy/example_object.hh"
cxx_class = "gem5::ExampleObject"
number = Param.Int(0, "test number")
我們可以為這個 python class 新增一些參數
在這個例子裡面,我替這個 SimObject 加上了一個 integer 參數 number
number = Param.Int(0, "test number")
在第五步可以來看看這個參數有什麼作用。
這是完整的 header 檔案,接下來稍微做一些筆記
{ src/learning_gem5/tommy/example_object.hh }
#ifndef __EXAMPLE_OBJECT_HH__
#define __EXAMPLE_OBJECT_HH__
#include "params/ExampleObject.hh"
#include "sim/sim_object.hh"
namespace gem5
{
class ExampleObject : public SimObject
{
public:
ExampleObject(const ExampleObjectParams &p);
};
} // namespace gem5
這個 header 檔案是在編譯的過程中,會被自動產生的。
檔案的位置會在 gem5/build/RISCV/params/ExampleObject.hh
#include "params/ExampleObject.hh"
當我們想要實作一個 SimObject,就需要繼承 class SimObject。
class ExampleObject : public SimObject
ExampleObjectParams 會放在自動生成的 params/ExampleObject.hh 裡面。
這代表了該 SimObject 的參數。
ExampleObject(const ExampleObjectParams &p);
例如我們在 python class 裡面有設定一個整數參數 number
number = Param.Int(0, "test number")
那在 params/ExampleObject.hh 裡面就會產生相對應的 int number
struct ExampleObjectParams
: public SimObjectParams
{
gem5::ExampleObject * create() const;
int number;
};
在 source file 這邊需要實作 SimObject 行為。
因為目前的範例很簡單,這邊只有放它的建構子。
我們拿到參數 ( number ) 之後,嘗試去輸出參數的值。
{ src/learning_gem5/tommy/example_object.cc }
#include "learning_gem5/tommy/example_object.hh"
#include <iostream>
namespace gem5
{
ExampleObject::ExampleObject(const ExampleObjectParams ¶ms)
: SimObject(params)
{
std::cout << "test number : " << params.number << std::endl;
std::cout << "Hello World! From a SimObject!" << std::endl;
}
} // namespace gem5
把來自 configuration script 的參數值列印出來,檢查一下有沒有成功拿到參數值。
std::cout << "test number : " << params.number << std::endl;
當我們建立了一個新的 SimObject 之後,或是我們在任何時候新增了一個 *.cc 檔案,我們都需要去修改 SConscript
這是為了讓 build system 可以知道我們新增了哪些 SimObject,或是新增了哪些檔案。
{ src/learning_gem5/tommy/SConscript }
Import('*')
SimObject('ExampleObject.py', sim_objects=['ExampleObject'])
Source('example_object.cc')
每當我們修改 SimObject 相關的檔案,例如:
都會需要重新編譯!
scons build/RISCV/gem5.debug -j$(nproc)
因為 configuration script 是 python ,我們也可以直接使用 python 的套件 argparse 來幫我們解析命令列,並直接從命令列帶入 SimObject 的參數。
這邊的例子就是從命令列取得 example-number,並將這個整數餵給 ExampleObject
{ configs/learning_gem5/tommy/example.py }
import argparse
import m5
from m5.objects import *
# -------------- options -------------- #
parser = argparse.ArgumentParser()
parser.add_argument(
'--example-number',
action="store",
type=int,
default=5,
help='An example number'
)
args = parser.parse_args()
# ------------------------------------- #
print("test print in the configuration file!")
root = Root(full_system=False)
root.example = ExampleObject()
root.example.number = args.example_number
m5.instantiate()
print("Beginning simulation!")
exit_event = m5.simulate()
print(f"Exiting @ tick {m5.curTick()} because {exit_event.getCause()}")
這邊可以體驗一下, gem5 不需要重新編譯,就可以設定參數的能力
例如說,我現在想要測試 L1 Cache 的 size 從 64 bytes 變成 128 bytes 的時候,對特定 workload 的影響多大,就可以在 configuration script 裡面直接設定這個 Cache ( 通常會是一個 SimObject ) 的 size ( 這個 SimObject 的參數 )
然而這邊的例子非常簡陋,只需要把一個整數傳進去,並確定輸出會跟著改變
# 假如什麼都不輸入,就會輸出預設數字 5
./build/RISCV/gem5.debug ./configs/learning_gem5/tommy/example.py
test number : 5
# 假如在命令列給它 100,它就會輸出 100
./build/RISCV/gem5.debug ./configs/learning_gem5/tommy/example.py --example-number 100
test number : 100
python configuration file
範例 : configs/learning_gem5/tommy/example.py
我們可以用 configuration script 去配置我們的 virtual platform,更改這個檔案 不需要 重新編譯
python class for SimObject
範例 : src/learning_gem5/tommy/ExampleObject.py
在 gem5 內的所有 SimObject 都需要有 python class,並且更改這個檔案後 需要 重新編譯。