DualCoreでL2キャッシュの同じラインを取り合うようなプログラムを作ってみることにする。
試してみるのはFalse Sharingのテストで、同じキャッシュラインで別の場所に別のコアが値を書き込み続け、そのキャッシュラインを複数のコアが取り合うようなコードだ。
#include <stdint.h> #define CSR_MHARTID (0xf14) #define read_csr(reg) ({ unsigned long __tmp; \ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ __tmp; }) volatile struct false_sharing_data_t { int32_t core_data[16] __attribute__((aligned(64))); } false_share_data; void slave_main(int hartid); int main (int hartid) { if (hartid == 0) { for (int i = 0; i < 16; i++) { false_share_data.core_data[i] = 0; } } slave_main(hartid); } void slave_main(int hartid) { printf ("hartid = %d\n", hartid); for (int i = 0; i < 2000; i++) { false_share_data.core_data[hartid]++; } }
false_share_data
のラインを各コアがアップデートする(ただし書き込む場所はそれぞれのコアでことなるのでAtomic性を考える必要はない)。以下のようにしてコンパイルし、バイナリを作ってみることにする。
$ riscv64-unknown-elf-gcc -static -mcmodel=medany -fno-common -fno-builtin-printf -nostdlib -nostartfiles -lm \ -lgcc -T link.ld syscalls.c crt.S main.c -o main.riscv
以下のようにしてChipyard上の2コア環境で動かしてみることにする。
$ ./simulator-chipyard-DualMediumBoomConfig-debug --vcd=false_sharing.dual.vcd \ --verbose ../../software/test/false_sharing/main.riscv 2>&1 | tee false_sharing.dual.log
結果を確認してみる。あれ、1コア分しか動いてないなあ。。。?
$ grep -v DASM false_sharing.dual.log
using random seed 1622245092 This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1. Listening on port 53315 hartid = 0 *** PASSED *** Completed after 87700 cycles [UART] UART0 is here (stdin/stdout).
ログ自体はコア番号が出力されないのでどのコアが何を実行しているのか良く分からない。ログ出力をちょっと変えてみよう。
diff --git a/src/main/scala/exu/core.scala b/src/main/scala/exu/core.scala index 579fce89..6f89e067 100644 --- a/src/main/scala/exu/core.scala +++ b/src/main/scala/exu/core.scala @@ -1334,14 +1334,16 @@ class BoomCore(usingTrace: Boolean)(implicit p: Parameters) extends BoomModule // To allow for diffs against spike :/ def printf_inst(uop: MicroOp) = { when (uop.is_rvc) { - printf("(0x%x)", uop.debug_inst(15,0)) + printf("DASM(0x%x)", uop.debug_inst(15,0)) } .otherwise { - printf("(0x%x)", uop.debug_inst) + printf("DASM(0x%x)", uop.debug_inst) } } when (rob.io.commit.arch_valids(w)) { - printf("%d 0x%x ", + printf("%d %d %d 0x%x ", + csr.io.hartid, + csr.io.time, priv, Sext(rob.io.commit.uops(w).debug_pc(vaddrBits-1,0), xLen)) printf_inst(rob.io.commit.uops(w))