Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
nexus-am
提交
4ab7a3b5
N
nexus-am
项目概览
OpenXiangShan
/
nexus-am
10 个月 前同步成功
通知
0
Star
21
Fork
25
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
N
nexus-am
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
4ab7a3b5
编写于
7月 06, 2022
作者:
X
XiChen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
hpm: add Readme && simplify hpmdriver.c as an example
上级
1ae8fb4a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
60 addition
and
130 deletion
+60
-130
apps/hpmdriver/Readme.md
apps/hpmdriver/Readme.md
+42
-0
apps/hpmdriver/hpmdriver.c
apps/hpmdriver/hpmdriver.c
+11
-129
apps/hpmdriver/hpmdriver.h
apps/hpmdriver/hpmdriver.h
+7
-1
未找到文件。
apps/hpmdriver/Readme.md
0 → 100644
浏览文件 @
4ab7a3b5
# HPM driver用法
## 环境
[
nexus-am仓库地址
](
https://github.com/OpenXiangShan/nexus-am/tree/southlake
)
,采用
`southlake`
分支。用法见
[
开发环境文档
](
https://xiangshan-doc.readthedocs.io/zh_CN/latest/tools/xsenv/
)
nexus-am/apps/hpmdriver
-
Makefile
-
events.h :性能事件编码表
-
hpmdriver.h :头文件,包含性能时间寄存器结构和各类功能函数
-
hpmdriver.c :主函数
采用
`make ARCH=riscv64-xs-southlake`
编译,可以采用如下指令编译+运行
```
shell
make
ARCH
=
riscv64-xs-southlake
&&
$NOOP_HOME
/build/emu
--no-diff
-i
./build/
*
.bin 2>&1 |
tee
log | less
```
## 使用方法
向性能事件寄存器
`mhpmevent`
中写入
`希望统计的性能事件`
,以及
`多个性能事件之间的组合方式`
(可以采用头文件中的宏定义)。然后读取对应的
`mhpmcounter`
寄存器,即可获得计数值。
mode域指定了,统计该特权级下的性能事件。
性能计数事件的组合方式:
-
Event0
\<
Optype0
\>
Event1 = T1
-
Event2
\<
Optype1
\>
Event3 = T2
-
T1
\<
Optype2
\>
T2 = Result
**特别注意,性能事件必须用其对应的性能事件寄存器统计**
,具体见下表。因为各个Block的
`Hardware Performance Monitor`
只与对应范围的
`csr mhpmevent`
寄存器相连,所以只能利用对应范围的
`mhpmevent`
寄存器去统计。而且各个Block性能事件的编码均从0开始,如果没有利用正确的性能事件,则会导致统计结果出错。
| 事件 | 对应的寄存器 |
| ------------- | ---- |
| Frontend |
`mhpmevent3~10`
|
| CtrlBlock |
`mhpmevent11~18`
|
| MemBlock |
`mhpmevent19~26`
|
| 缓存 |
`mhpmevent27~31`
|
具体示例,可以参考
`hpmdriver.c`
apps/hpmdriver/hpmdriver.c
浏览文件 @
4ab7a3b5
#include "hpmdriver.h"
#define PRINT_SEP(...) printf("-------------------- %s --------------------\n", __VA_ARGS__);
int
main
()
{
printf
(
"Hello, XiangShan!
\n
"
);
print
f
(
"marchid: %ld
\n
"
,
csr_read
(
marchid
)
);
print
f
(
"mcountinhibit: %ld
\n
"
,
csr_read
(
mcountinhibit
)
);
print
f
(
"mcounteren: %ld
\n
"
,
csr_read
(
mcounteren
)
);
print
f
(
"scounteren: %ld
\n
"
,
csr_read
(
scounteren
)
);
print
f
(
"mcycle: %ld
\n
"
,
csr_read
(
mcycle
)
);
print
f
(
"minstret: %ld
\n
"
,
csr_read
(
minstret
)
);
print
d_csr
(
marchid
);
print
x_csr
(
mcountinhibit
);
print
x_csr
(
mcounteren
);
print
x_csr
(
scounteren
);
print
d_csr
(
mcycle
);
print
d_csr
(
minstret
);
se_cc_single
(
3
,
MODE_M
,
Frontend_frontendFlush
);
se_cc_single
(
11
,
MODE_M
,
Frontend_frontendFlush
);
se_cc_single
(
11
,
MODE_M
,
CtrlBlock_decoder_waitInstr
);
se_cc_double
(
19
,
MODE_M
,
OPTYPE_ADD
,
MemBlock_loadpipe0_load_req
,
MemBlock_loadpipe1_load_req
);
// === tmp workload ===
volatile
uint64_t
a
=
0
;
...
...
@@ -27,125 +26,8 @@ int main() {
print_counter
(
3
);
print_event
(
11
);
print_counter
(
11
);
#if 0
uint64_t set_mode_M = (0x1UL << 63);
// ===== frontend ==================================================
csr_write(mhpmevent3, csr_read(mhpmevent3)|set_mode_M);
csr_write(mhpmevent4, csr_read(mhpmevent4)|set_mode_M|0x1UL);
csr_write(mhpmevent5, csr_read(mhpmevent5)|set_mode_M|0x2UL);
csr_write(mhpmevent6, csr_read(mhpmevent6)|set_mode_M|0x3UL);
csr_write(mhpmevent7, csr_read(mhpmevent7)|set_mode_M|0x10UL);
csr_write(mhpmevent8, csr_read(mhpmevent8)|set_mode_M|0xFFFFFFFFUL);
csr_write(mhpmevent9, csr_read(mhpmevent9)|set_mode_M|0x00000081UL);
csr_write(mhpmevent10, csr_read(mhpmevent10)|set_mode_M);
// ======= ctrl ==================================================
csr_write(mhpmevent11, csr_read(mhpmevent11)|set_mode_M|0x1UL);
csr_write(mhpmevent12, csr_read(mhpmevent12)|set_mode_M|0x2UL);
csr_write(mhpmevent13, csr_read(mhpmevent13)|set_mode_M|0x3UL);
csr_write(mhpmevent14, csr_read(mhpmevent14)|set_mode_M|0x10UL);
csr_write(mhpmevent15, csr_read(mhpmevent15)|set_mode_M|0xFFFFFFFFUL);
csr_write(mhpmevent16, csr_read(mhpmevent16)|set_mode_M);
csr_write(mhpmevent17, csr_read(mhpmevent17)|set_mode_M);
csr_write(mhpmevent18, csr_read(mhpmevent18)|set_mode_M);
// ======== memory ===================================================
csr_write(mhpmevent19, csr_read(mhpmevent19)|set_mode_M);
csr_write(mhpmevent20, csr_read(mhpmevent20)|set_mode_M|0x1UL);
csr_write(mhpmevent21, csr_read(mhpmevent21)|set_mode_M|0x2UL);
csr_write(mhpmevent22, csr_read(mhpmevent22)|set_mode_M|0x3UL);
csr_write(mhpmevent23, csr_read(mhpmevent23)|set_mode_M|43);
csr_write(mhpmevent24, csr_read(mhpmevent24)|set_mode_M|52);
csr_write(mhpmevent25, csr_read(mhpmevent25)|set_mode_M|52);
csr_write(mhpmevent26, csr_read(mhpmevent26)|set_mode_M|43);
// ======== hc ================================================
csr_write(mhpmevent27, csr_read(mhpmevent27)|set_mode_M);
csr_write(mhpmevent28, csr_read(mhpmevent28)|set_mode_M|0x1UL);
csr_write(mhpmevent29, csr_read(mhpmevent29)|set_mode_M|0x2UL);
csr_write(mhpmevent30, csr_read(mhpmevent30)|set_mode_M|0x3UL);
csr_write(mhpmevent31, csr_read(mhpmevent31)|set_mode_M|0xFFFFFFFFUL);
// csr write mhpmcounter 3 to 31 0x0
csr_write(mhpmcounter3, 0x0UL);
csr_write(mhpmcounter4, 0x0UL);
csr_write(mhpmcounter5, 0x0UL);
csr_write(mhpmcounter6, 0x0UL);
csr_write(mhpmcounter7, 0x0UL);
csr_write(mhpmcounter8, 0x0UL);
csr_write(mhpmcounter9, 0x0UL);
csr_write(mhpmcounter10, 0x0UL);
csr_write(mhpmcounter11, 0x0UL);
csr_write(mhpmcounter12, 0x0UL);
csr_write(mhpmcounter13, 0x0UL);
csr_write(mhpmcounter14, 0x0UL);
csr_write(mhpmcounter15, 0x0UL);
csr_write(mhpmcounter16, 0x0UL);
csr_write(mhpmcounter17, 0x0UL);
csr_write(mhpmcounter18, 0x0UL);
csr_write(mhpmcounter19, 0x0UL);
csr_write(mhpmcounter20, 0x0UL);
csr_write(mhpmcounter21, 0x0UL);
csr_write(mhpmcounter22, 0x0UL);
csr_write(mhpmcounter23, 0x0UL);
csr_write(mhpmcounter24, 0x0UL);
csr_write(mhpmcounter25, 0x0UL);
csr_write(mhpmcounter26, 0x0UL);
csr_write(mhpmcounter27, 0x0UL);
csr_write(mhpmcounter28, 0x0UL);
csr_write(mhpmcounter29, 0x0UL);
csr_write(mhpmcounter30, 0x0UL);
csr_write(mhpmcounter31, 0x0UL);
csr_write(mcycle, 0x0UL);
csr_write(minstret, 0x0UL);
// ================================================================
volatile uint64_t a = 0;
for(uint64_t i = 0; i < 100; i++) {
a += a + i;
}
printf("%lu\n",a);
// ================================================================
PRINT_SEP("frontend");
printf("mhpmevent3: %lx, mhpmcounter3: %ld\n", csr_read(mhpmevent3), csr_read(mhpmcounter3));
printf("mhpmevent4: %lx, mhpmcounter4: %ld\n", csr_read(mhpmevent4), csr_read(mhpmcounter4));
printf("mhpmevent5: %lx, mhpmcounter5: %ld\n", csr_read(mhpmevent5), csr_read(mhpmcounter5));
printf("mhpmevent6: %lx, mhpmcounter6: %ld\n", csr_read(mhpmevent6), csr_read(mhpmcounter6));
printf("mhpmevent7: %lx, mhpmcounter7: %ld\n", csr_read(mhpmevent7), csr_read(mhpmcounter7));
printf("mhpmevent8: %lx, mhpmcounter8: %ld\n", csr_read(mhpmevent8), csr_read(mhpmcounter8));
printf("mhpmevent9: %lx, mhpmcounter9: %ld\n", csr_read(mhpmevent9), csr_read(mhpmcounter9));
printf("mhpmevent10: %lx, mhpmcounter10: %ld\n", csr_read(mhpmevent10), csr_read(mhpmcounter10));
PRINT_SEP("ctrl");
printf("mhpmevent11: %lx, mhpmcounter11: %ld\n", csr_read(mhpmevent11), csr_read(mhpmcounter11));
printf("mhpmevent12: %lx, mhpmcounter12: %ld\n", csr_read(mhpmevent12), csr_read(mhpmcounter12));
printf("mhpmevent13: %lx, mhpmcounter13: %ld\n", csr_read(mhpmevent13), csr_read(mhpmcounter13));
printf("mhpmevent14: %lx, mhpmcounter14: %ld\n", csr_read(mhpmevent14), csr_read(mhpmcounter14));
printf("mhpmevent15: %lx, mhpmcounter15: %ld\n", csr_read(mhpmevent15), csr_read(mhpmcounter15));
printf("mhpmevent16: %lx, mhpmcounter16: %ld\n", csr_read(mhpmevent16), csr_read(mhpmcounter16));
printf("mhpmevent17: %lx, mhpmcounter17: %ld\n", csr_read(mhpmevent17), csr_read(mhpmcounter17));
PRINT_SEP("memory");
printf("mhpmevent18: %lx, mhpmcounter18: %ld\n", csr_read(mhpmevent18), csr_read(mhpmcounter18));
printf("mhpmevent19: %lx, mhpmcounter19: %ld\n", csr_read(mhpmevent19), csr_read(mhpmcounter19));
printf("mhpmevent20: %lx, mhpmcounter20: %ld\n", csr_read(mhpmevent20), csr_read(mhpmcounter20));
printf("mhpmevent21: %lx, mhpmcounter21: %ld\n", csr_read(mhpmevent21), csr_read(mhpmcounter21));
printf("mhpmevent22: %lx, mhpmcounter22: %ld\n", csr_read(mhpmevent22), csr_read(mhpmcounter22));
printf("mhpmevent23: %lx, mhpmcounter23: %ld\n", csr_read(mhpmevent23), csr_read(mhpmcounter23));
printf("mhpmevent24: %lx, mhpmcounter24: %ld\n", csr_read(mhpmevent24), csr_read(mhpmcounter24));
printf("mhpmevent25: %lx, mhpmcounter25: %ld\n", csr_read(mhpmevent25), csr_read(mhpmcounter25));
printf("mhpmevent26: %lx, mhpmcounter26: %ld\n", csr_read(mhpmevent26), csr_read(mhpmcounter26));
PRINT_SEP("hc");
printf("mhpmevent27: %lx, mhpmcounter27: %ld\n", csr_read(mhpmevent27), csr_read(mhpmcounter27));
printf("mhpmevent28: %lx, mhpmcounter28: %ld\n", csr_read(mhpmevent28), csr_read(mhpmcounter28));
printf("mhpmevent29: %lx, mhpmcounter29: %ld\n", csr_read(mhpmevent29), csr_read(mhpmcounter29));
printf("mhpmevent30: %lx, mhpmcounter30: %ld\n", csr_read(mhpmevent30), csr_read(mhpmcounter30));
printf("mhpmevent31: %lx, mhpmcounter31: %ld\n", csr_read(mhpmevent31), csr_read(mhpmcounter31));
printf("mcycle: %ld\n", csr_read(mcycle));
printf("mhpmcounter8: %ld\n", csr_read(mhpmcounter8));
printf("mhpmcounter15: %ld\n", csr_read(mhpmcounter15));
printf("mhpmcounter24: %ld\n", csr_read(mhpmcounter24));
// ================================================================
PRINT_SEP("end");
#endif
print_event
(
19
);
print_counter
(
19
);
return
0
;
}
\ No newline at end of file
apps/hpmdriver/hpmdriver.h
浏览文件 @
4ab7a3b5
...
...
@@ -2,7 +2,7 @@
#define __HPMDRIVER_H_
#include <klib.h>
#include <csr.h>
#include <csr.h>
// nexus-am/am/src/xs/include/csr.h
#include "events.h"
#define MODE_OFFSET 59
...
...
@@ -23,6 +23,10 @@
#define OPTYPE_AND 0x1
#define OPTYPE_XOR 0x2
#define OPTYPE_ADD 0x4
// Operations
// Event0 <Optype0> Event1 = T1
// Event2 <Optype1> Event3 = T2
// T1 <Optype2> T2 = Result
#define EVENT3_OFFSET 30
#define EVENT3_MASK 0x3FF
...
...
@@ -39,6 +43,8 @@
#define print_event(id) printf("mhpmevent%d: %lx\n", id, csr_read(mhpmevent##id))
#define clear_counter(id) csr_write(mhpmcounter##id, 0x0UL)
#define print_counter(id) printf("mhpmcounter%d: %lu\n", id, csr_read(mhpmcounter##id))
#define printd_csr(csr) printf(#csr": %ld\n", csr_read(csr))
#define printx_csr(csr) printf(#csr": %lx\n", csr_read(csr))
#define set_event_quad(csr_id, mode, optype2, optype1, optype0, event3, event2, event1, event0) \
{ \
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录