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,
- 過去の記事: