iT邦幫忙

0

[gem5] 建立一個簡單的 SimObject 並進行模擬

  • 分享至 

  • xImage
  •  

系列文章 : [gem5] 從零開始的 gem5 學習筆記

從這邊開始,就可以寫一些簡單的程式碼了!
其實這一篇的內容絕大部分來自 gem5 的官方教學 learning gem5 / Creating a very simple SimObject,這邊簡單做個中文的筆記。

雖然說是中文的筆記,結果到最後還是落得中英夾雜的晶晶體,只能說我的文學造詣還是有待加強...

在這時候,我們可以開始建立一個新的 SimObject
SimObject 在 gem5 裡是一個 C++ 與 python 間的橋樑,當我們用 C++/python 裡實作一個 SimObject 之後,就可以在 python configuration script 裡面使用。



在這個範例,我們需要新增 5 個檔案

  • src/learning_gem5/tommy/ExampleObject.py
  • src/learning_gem5/tommy/example_object.cc
  • src/learning_gem5/tommy/example_object.hh
  • src/learning_gem5/tommy/SConscript
  • configs/learning_gem5/tommy/example.py


第零步 : 嘗試運行範例

一開始可以先把簡單的範例編譯起來, 然後運行看看會不會出現問題

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

每一個 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")

第五步可以來看看這個參數有什麼作用。

第二步 : 用 C++ 實作一個 SimObject

這是完整的 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 &params)
    : 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

當我們建立了一個新的 SimObject 之後,或是我們在任何時候新增了一個 *.cc 檔案,我們都需要去修改 SConscript

這是為了讓 build system 可以知道我們新增了哪些 SimObject,或是新增了哪些檔案。

{ src/learning_gem5/tommy/SConscript }

Import('*')

SimObject('ExampleObject.py', sim_objects=['ExampleObject'])
    
Source('example_object.cc')
  • ExampleObject.py : python class
  • ExampleObject : 我們想要新增的 SimObject
  • example_object.cc : 我們想要加進 build system 的 source file ( *.cc file )

第四步 : 重新編譯

每當我們修改 SimObject 相關的檔案,例如:

  • src/learning_gem5/tommy/ExampleObject.py
  • src/learning_gem5/tommy/example_object.cc
  • src/learning_gem5/tommy/example_object.hh
  • src/learning_gem5/tommy/SConscript

都會需要重新編譯!

scons build/RISCV/gem5.debug -j$(nproc)

第五步 : 實作 python configuration script

因為 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,並且更改這個檔案後 需要 重新編譯。

參考連結


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言