Learn gem5 #3 (Creating a very simple SimObject, Debugging gem5)

Creating a very simple SimObject

https://www.gem5.org/documentation/learning_gem5/part2/helloobject/

とりあえず書いてあるとおりに作業を進める。
バックアップしてスクラッチから書いていく。

$ git checkout -b hello-simobject
$ mkdir -p backup/src/learning_gem5
$ mv src/learning_gem5/part2 backup/src/learning_gem5
$ mkdir -p backup/configs/learning_gem5
$ mv configs/learning_gem5/part2 backup/configs/learning_gem5
$ mkdir -p src/learning_gem5/part2
$ mkdir -p configs/learning_gem5/part2

src/learning_gem5/part2/HelloObject.py

from m5.params import *
from m5.SimObject import SimObject

class HelloObject(SimObject):
    type = 'HelloObject'
    cxx_header = "learning_gem5/part2/hello_object.hh"
    cxx_class = "gem5::HelloObject"

src/learning_gem5/part2/hello_object.hh

#ifndef __LEARNING_GEM5_HELLO_OBJECT_HH__
#define __LEARNING_GEM5_HELLO_OBJECT_HH__

#include "params/HelloObject.hh"
#include "sim/sim_object.hh"

namespace gem5
{

class HelloObject : public SimObject
{
  public:
    HelloObject(const HelloObjectParams &p);
};

} // namespace gem5

#endif // __LEARNING_GEM5_HELLO_OBJECT_HH__

src/learning_gem5/part2/hello_object.cc

#include "learning_gem5/part2/hello_object.hh"

#include <iostream>

namespace gem5
{

HelloObject::HelloObject(const HelloObjectParams &params) :
    SimObject(params)
{
    std::cout << "Hello World! From a SimObject!" << std::endl;
}

} // namespace gem5

src/learning_gem5/part2/SConscript

Import('*')

SimObject('HelloObject.py', sim_objects=['HelloObject'])
Source('hello_object.cc')

なんと、再ビルドが必要!!キャッシュがあっても -j20 オプションで2分ぐらいかかる。

$ scons build/X86/gem5.opt -j20

次に構成スクリプトの作成
configs/learning_gem5/part2/run_hello.py

import m5
from m5.objects import *

root = Root(full_system = False)
root.hello = HelloObject()
m5.instantiate()

print("Beginning simulation!")
exit_event = m5.simulate()
print('Exiting @ tick {} because {}'
      .format(m5.curTick(), exit_event.getCause()))

実行

$ build/X86/gem5.opt configs/learning_gem5/part2/run_hello.py

実行できたようだ。

gem5 Simulator System.  https://www.gem5.org
gem5 is copyrighted software; use the --copyright option for details.

gem5 version 23.1.0.0
gem5 compiled Mar 24 2024 16:00:21
gem5 started Mar 24 2024 16:04:37
gem5 executing on DESKTOP-1L01RQ8, pid 3549
command line: build/X86/gem5.opt configs/learning_gem5/part2/run_hello.py

Global frequency set at 1000000000000 ticks per second
warn: No dot file generated. Please install pydot to generate the dot file and pdf.
Hello World! From a SimObject!
Beginning simulation!
src/sim/simulate.cc:199: info: Entering event queue @ 0.  Starting simulation...
Exiting @ tick 18446744073709551615 because simulate() limit reached

Debugging gem5

Using debug flags

DRAMデバッグログを見る

$ build/X86/gem5.opt --debug-flags=DRAM configs/learning_gem5/part1/simple.py | head -n 50

CPUのデバッグログを見る。

$ build/X86/gem5.opt --debug-flags=Exec configs/learning_gem5/part1/simple.py | head -n 50

Execのデバッグフラグはいくつかのデバッグフラグの集合になっている。詳細は以下で確認できる。

$ build/X86/gem5.opt --debug-help

Adding a new debug flag

カスタムのデバッグフラグを追加できるらしい。

src/learning_gem5/part2/SConscript に以下を追加。

DebugFlag('HelloExample')

これで自動的にデバッグ用のヘッダファイルが追加される。これをインクルードする。
src/learning_gem5/part2/hello_object.cc

#include "base/trace.hh"
#include "debug/HelloExample.hh"
-    std::cout << "Hello World! From a SimObject!" << std::endl;
+    DPRINTF(HelloExample, "Created the hello object\n");

ビルドして実行。

$ scons build/X86/gem5.opt -j20
$ build/X86/gem5.opt --debug-flags=HelloExample configs/learning_gem5/part2/run_hello.py

実行できた。

gem5 Simulator System.  https://www.gem5.org
gem5 is copyrighted software; use the --copyright option for details.

gem5 version 23.1.0.0
gem5 compiled Mar 24 2024 16:17:31
gem5 started Mar 24 2024 16:19:16
gem5 executing on DESKTOP-1L01RQ8, pid 3713
command line: build/X86/gem5.opt --debug-flags=HelloExample configs/learning_gem5/part2/run_hello.py

Global frequency set at 1000000000000 ticks per second
warn: No dot file generated. Please install pydot to generate the dot file and pdf.
      0: hello: Created the hello object
Beginning simulation!
src/sim/simulate.cc:199: info: Entering event queue @ 0.  Starting simulation...
Exiting @ tick 18446744073709551615 because simulate() limit reached

Debug output

DPRINTFは以下を出力する。

  • 現在時刻の tick 値
  • DPRINTF呼び出し元のSimObject名。通常Pythonでの変数名だが、SimObjectのname()関数の戻り値を出力。
  • 書式化済みメッセージ文字列

デバッグ出力先は --debug-file オプションで制御できる。デフォルトは stdout。

Using functions other than DPRINTF

DPRINTF以外にもデバッグ関数はいろいろある。リファレンスを参照。
https://doxygen.gem5.org/release/current/base_2trace_8hh.html

opt, debug ビルド以外はデバッグ出力は無効化されるのでデバッグ出力をしたい場合は gem5.opt, gem5.debug ファイルを実行する。