サイクル精度シミュレータSniperでは、計測範囲を指定する用語としてROI(Region of Interest)というものがある。 通常、サイクル数などはこの範囲を計測するのだが、これを取得する方法はいくつかあって、Sniperは基本的にC言語用のマクロを用意している。
ここにはRISC-V用のROI関数が定義されていないので、無理やり自分で定義する。x0への書き込み命令(ADDI x0)をROI用の関数として定義してしまう。
#if defined(__riscv) #define SimMagic0(cmd) ({ \ asm volatile ( \ "addi x0, x0, %0\n" \ :: "i"(cmd) \ ); \ }) #define SimRoiStart() SimMagic0(SIM_CMD_ROI_START) #define SimRoiEnd() SimMagic0(SIM_CMD_ROI_END)
そしてこれらをテストベンチマーク上に埋め込むようにする。
SimRoiStart(); spmv(R, val, idx, x, ptr, y); SimRoiEnd();
SniperはSIFTファイル生成用にSpikeを使用するので、Spike側を改造してMagicを送信するようにしてみる。
riscv/execute.cc
} else { p->get_state()->log_writer->Instruction(addr, size, num_addresses, addresses, is_branch, taken, 0 /*is_predicate*/, 1 /*executed*/); if ((MASK_ADDI & sift_executed_insn) == MATCH_ADDI) { if ((INSN_FIELD_IMM12 & sift_executed_insn) == 0x00100000) { p->get_state()->log_writer->Magic (1, 0, 0); } if ((INSN_FIELD_IMM12 & sift_executed_insn) == 0x00200000) { p->get_state()->log_writer->Magic (2, 0, 0); } } }
ここまでは良かったが、SniperのSIFT Writer/SIFT ReaderはResponseを想定しているらしく、これがよく分からない。Magicを送信するだけで、なんでそんなことがいるんだ?
とりあえず余計な部分をコメントアウトして試行してみる。
diff --git a/sift/sift_reader.cc b/sift/sift_reader.cc index 300371c..2cf2c0c 100644 --- a/sift/sift_reader.cc +++ b/sift/sift_reader.cc @@ -752,21 +752,21 @@ void Sift::Reader::sendSimpleResponse(RecOtherType type, void *data, uint32_t si std::cerr << "[DEBUG:" << m_id << "] Write SimpleResponse type=" << type << std::endl; #endif - if (!initResponse()) - { - std::cerr << "[SIFT:" << m_id << "] Error: initResponse failed\n"; - } - - Record rec; - rec.Other.zero = 0; - rec.Other.type = type; - rec.Other.size = size; - response->write(reinterpret_cast<char*>(&rec), sizeof(rec.Other)); - if (size > 0) - { - response->write(reinterpret_cast<char*>(data), size); - } - response->flush(); + // if (!initResponse()) + // { + // std::cerr << "[SIFT:" << m_id << "] Error: initResponse failed\n"; + // } + // + // Record rec; + // rec.Other.zero = 0; + // rec.Other.type = type; + // rec.Other.size = size; + // response->write(reinterpret_cast<char*>(&rec), sizeof(rec.Other)); + // if (size > 0) + // { + // response->write(reinterpret_cast<char*>(data), size); + // } + // response->flush(); } uint64_t Sift::Reader::getPosition() diff --git a/sift/sift_writer.cc b/sift/sift_writer.cc index 387afd0..20feeaf 100644 --- a/sift/sift_writer.cc +++ b/sift/sift_writer.cc @@ -757,6 +757,8 @@ uint64_t Sift::Writer::Magic(uint64_t a, uint64_t b, uint64_t c) output->write(reinterpret_cast<char*>(&c), sizeof(uint64_t)); output->flush(); + return 0; + initResponse(); // wait for reply