FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

ChampSimの環境構築メモ (2. トレースファイルの構成について調査する)

ChampSimの構築メモ:トレースファイルの構成について調査する。

$ ./bin/champsim --help
WARNING: physical memory size is smaller than virtual memory size.
A microarchitecture simulator for research and education
Usage: ./bin/champsim [OPTIONS] traces

Positionals:
  traces TEXT:FILE REQUIRED   The paths to the traces

Options:
  -h,--help                   Print this help message and exit
  -c,--cloudsuite             Read all traces using the cloudsuite format
  --hide-heartbeat            Hide the heartbeat output
  -w,--warmup-instructions UINT Excludes: --warmup_instructions
                              The number of instructions in the warmup phase
  --warmup_instructions UINT Excludes: --warmup-instructions
                              [deprecated] use --warmup-instructions instead
  -i,--simulation-instructions UINT Excludes: --simulation_instructions
                              The number of instructions in the detailed phase. If not specified, run to the end of the trace.
  --simulation_instructions UINT Excludes: --simulation-instructions
                              [deprecated] use --simulation-instructions instead
  --json TEXT                 The name of the file to receive JSON output. If no name is specified, stdout will be used

pinのインストール

$ mkdir pintool
$ cd pintool
$ wget https://software.intel.com/sites/landingpage/pintool/downloads/pin-3.22-98547-g7a303a835-gcc-linux.tar.gz
$ tar xvfz pin-3.22-98547-g7a303a835-gcc-linux.tar.gz
$ cd pin-3.22-98547-g7a303a835-gcc-linux/source/tools
$ make -j$(nproc)
$ export PIN_ROOT=/home/msyksphinz/work/champsim/pintool/pin-3.22-98547-g7a303a835-gcc-linux

ChampSimのディレクトリに戻ってくる:

$ cd ${CHAMPSIM}/tracer/pin
$ make

これにより、obj-intel64/chamsim_tracer.so が生成される。これを使ってトレースファイルを生成するというわけだ。以下のコマンドは、x86のlsコマンドのトレースファイルを取得するためのコマンドだ。

$ mkdir -p traces
$ ../../../pintool/pin-3.22-98547-g7a303a835-gcc-linux/pin \
        -t obj-intel64/champsim_tracer.so \
        -o traces/ls_trace.champsim \
        -s 100000 -t 200000 -- ls

このtraces/ls_trace.champsim自体はバイナリ化されており、hexdumpしても構成は良く分からない。

たぶんバイナリで生成されるようなモードになっている。どのようなデータ構造で生成されているのかを調査してみる。

下記のようなデータ構造で作られているような気がしている。

  • inc/trace_instruction.h
struct input_instr {
  // instruction pointer or PC (Program Counter)
  unsigned long long ip;

  // branch info
  unsigned char is_branch;
  unsigned char branch_taken;

  unsigned char destination_registers[NUM_INSTR_DESTINATIONS]; // output registers
  unsigned char source_registers[NUM_INSTR_SOURCES];           // input registers

  unsigned long long destination_memory[NUM_INSTR_DESTINATIONS]; // output memory
  unsigned long long source_memory[NUM_INSTR_SOURCES];           // input memory
};

試しに、以下のようなトレースファイルダンプを作ってみた。

diff --git a/tracer/pin/champsim_tracer.cpp b/tracer/pin/champsim_tracer.cpp
index 0ce6452..1871e58 100644
--- a/tracer/pin/champsim_tracer.cpp
+++ b/tracer/pin/champsim_tracer.cpp
@@ -37,6 +37,7 @@ using trace_instr_format_t = input_instr;
 UINT64 instrCount = 0;

 std::ofstream outfile;
+std::ofstream outfile_debug;

 trace_instr_format_t curr_instr;

@@ -90,6 +91,32 @@ void WriteCurrentInstruction()
   typename decltype(outfile)::char_type buf[sizeof(trace_instr_format_t)];
   std::memcpy(buf, &curr_instr, sizeof(trace_instr_format_t));
   outfile.write(buf, sizeof(trace_instr_format_t));
+
+  outfile_debug << std::hex << curr_instr.ip << " (" << (curr_instr.is_branch ? (curr_instr.branch_taken ? "taken " : "untake") : "      ") << ")\n";
+  outfile_debug << "dest_regs : ";
+  for (size_t i = 0; i < NUM_INSTR_DESTINATIONS; i++) {
+    outfile_debug << std::hex << static_cast<uint32_t>(curr_instr.destination_registers[i]) << ", ";
+  }
+  outfile_debug << "\n";
+
+  outfile_debug << "source_regs : ";
+  for (size_t i = 0; i < NUM_INSTR_SOURCES; i++) {
+    outfile_debug << std::hex << static_cast<uint32_t>(curr_instr.source_registers[i]) << ", ";
+  }
+  outfile_debug << "\n";
+
+  outfile_debug << "dest_memory : ";
+  for (size_t i = 0; i < NUM_INSTR_DESTINATIONS; i++) {
+    outfile_debug << std::hex << curr_instr.destination_memory[i] << ", ";
+  }
+  outfile_debug << "\n";
+
+  outfile_debug << "source_memory : ";
+  for (size_t i = 0; i < NUM_INSTR_SOURCES; i++) {
+    outfile_debug << std::hex << curr_instr.source_memory[i] << ", ";
+  }
+  outfile_debug << "\n";
+
 }

 void BranchOrNot(UINT32 taken)
@@ -183,6 +210,12 @@ int main(int argc, char* argv[])
     exit(1);
   }

+  outfile_debug.open("champsim.trace_debug", std::ios_base::out | std::ios_base::trunc);
+  if (!outfile_debug) {
+    std::cout << "Couldn't open output trace debug file. Exiting." << std::endl;
+    exit(1);
+  }
+
   // Register function to be called to instrument instructions
   INS_AddInstrumentFunction(Instruction, 0);

以下のようなトレースファイルが生成された。書きこんだレジスタファイル、分岐の情報、メモリアクセスのアドレス情報が含まれているようだ。

特にメモリアクセスに関して、サイズ等の情報が含まれていない。フォワーディングなどの判断をするためには、サイズの情報が必要なのではないのかな?

7fbdf5464563 (taken )
dest_regs : 1a, 0,
source_regs : 1a, 19, 0, 0,
dest_memory : 0, 0,
source_memory : 0, 0, 0, 0,
7fbdf54643a8 (      )
dest_regs : 11, 0,
source_regs : 7, 0, 0, 0,
dest_memory : 0, 0,
source_memory : dfc9b760, 0, 0, 0,
7fbdf54643ac (      )
dest_regs : a, 0,
source_regs : 5, 0, 0, 0,
dest_memory : 0, 0,
source_memory : 2a54e980, 0, 0, 0,
7fbdf54643b3 (      )
dest_regs : 9, 0,
source_regs : 5, 0, 0, 0,
dest_memory : 0, 0,
source_memory : 2a54e990, 0, 0, 0,
7fbdf54643ba (      )
dest_regs : 3, 0,
source_regs : 5, 0, 0, 0,
dest_memory : 0, 0,
source_memory : 2a54e978, 0, 0, 0,

  • 過去の記事:

msyksphinz.hatenablog.com