测得的mcycle小于spike中的minstret
The measured mcycle is less than minstret in Spike
我用spike来运行 "riscv-tools/riscv-tests/build/benchmarks"中的测试程序:
$ spike multiply.riscv
并且输出显示:
mcycle = 24096
minstret = 24103
为什么 mcycle
小于 minstret
?
难道这意味着尖峰在一个周期内可以运行条以上的指令?
(我试图追踪尖峰代码,但找不到如何计算 mcycle。)
在这种情况下,mcycle 和 minstret 值的打印不是来自 Spike,而是来自测试(基准)。有代码:
https://github.com/ucb-bar/riscv-benchmarks/blob/master/common/syscalls.c
#define NUM_COUNTERS 2
static uintptr_t counters[NUM_COUNTERS];
static char* counter_names[NUM_COUNTERS];
static int handle_stats(int enable)
{
int i = 0;
#define READ_CTR(name) do { \
while (i >= NUM_COUNTERS) ; \
uintptr_t csr = read_csr(name); \
if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \
counters[i++] = csr; \
} while (0)
READ_CTR(mcycle);
READ_CTR(minstret);
#undef READ_CTR
return 0;
}
阅读 mcycle 和 minstret 之间有一些代码。现在您知道读数之间有多少代码了。
在 Spike 中,mcycle 和 minstret 根据定义总是相等的(它们由相同的代码处理):https://github.com/riscv/riscv-isa-sim/blob/9e012462f53113dc9ed00d7fbb89aeafeb9b89e9/riscv/processor.cc#L347
case CSR_MINSTRET:
case CSR_MCYCLE:
if (xlen == 32)
state.minstret = (state.minstret >> 32 << 32) | (val & 0xffffffffU);
else
state.minstret = val;
break;
syscalls.c 从 https://github.com/ucb-bar/riscv-benchmarks/blob/master/multiply/bmark.mk 链接到 multiply.riscv 二进制文件 - multiply_riscv_bin = multiply.riscv
$(multiply_riscv_bin): ... $(patsubst %.c, %.o, ... syscalls.c ... )
在syscalls.c函数中有_init
调用测试的main
并打印值,记录在SYS_stats"syscall"和handle_stats
.
void _init(int cid, int nc)
{
init_tls();
thread_entry(cid, nc);
// only single-threaded programs should ever get here.
int ret = main(0, 0);
char buf[NUM_COUNTERS * 32] __attribute__((aligned(64)));
char* pbuf = buf;
for (int i = 0; i < NUM_COUNTERS; i++)
if (counters[i])
pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]);
if (pbuf != buf)
printstr(buf);
exit(ret);
}
我用spike来运行 "riscv-tools/riscv-tests/build/benchmarks"中的测试程序:
$ spike multiply.riscv
并且输出显示:
mcycle = 24096
minstret = 24103
为什么 mcycle
小于 minstret
?
难道这意味着尖峰在一个周期内可以运行条以上的指令?
(我试图追踪尖峰代码,但找不到如何计算 mcycle。)
在这种情况下,mcycle 和 minstret 值的打印不是来自 Spike,而是来自测试(基准)。有代码:
https://github.com/ucb-bar/riscv-benchmarks/blob/master/common/syscalls.c
#define NUM_COUNTERS 2
static uintptr_t counters[NUM_COUNTERS];
static char* counter_names[NUM_COUNTERS];
static int handle_stats(int enable)
{
int i = 0;
#define READ_CTR(name) do { \
while (i >= NUM_COUNTERS) ; \
uintptr_t csr = read_csr(name); \
if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \
counters[i++] = csr; \
} while (0)
READ_CTR(mcycle);
READ_CTR(minstret);
#undef READ_CTR
return 0;
}
阅读 mcycle 和 minstret 之间有一些代码。现在您知道读数之间有多少代码了。
在 Spike 中,mcycle 和 minstret 根据定义总是相等的(它们由相同的代码处理):https://github.com/riscv/riscv-isa-sim/blob/9e012462f53113dc9ed00d7fbb89aeafeb9b89e9/riscv/processor.cc#L347
case CSR_MINSTRET:
case CSR_MCYCLE:
if (xlen == 32)
state.minstret = (state.minstret >> 32 << 32) | (val & 0xffffffffU);
else
state.minstret = val;
break;
syscalls.c 从 https://github.com/ucb-bar/riscv-benchmarks/blob/master/multiply/bmark.mk 链接到 multiply.riscv 二进制文件 - multiply_riscv_bin = multiply.riscv $(multiply_riscv_bin): ... $(patsubst %.c, %.o, ... syscalls.c ... )
在syscalls.c函数中有_init
调用测试的main
并打印值,记录在SYS_stats"syscall"和handle_stats
.
void _init(int cid, int nc)
{
init_tls();
thread_entry(cid, nc);
// only single-threaded programs should ever get here.
int ret = main(0, 0);
char buf[NUM_COUNTERS * 32] __attribute__((aligned(64)));
char* pbuf = buf;
for (int i = 0; i < NUM_COUNTERS; i++)
if (counters[i])
pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]);
if (pbuf != buf)
printstr(buf);
exit(ret);
}