1 Star 0 Fork 23

cxh/perftest

forked from src-openEuler/perftest 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0009-Get-CPU-cycles-on-RISC-V.patch 3.26 KB
一键复制 编辑 原始数据 按行查看 历史
From df20eb17a10aa4c930887c92a4d5a3832402a096 Mon Sep 17 00:00:00 2001
From: "v.v.mitrofanov" <[email protected]>
Date: Mon, 31 Jan 2022 13:41:30 +0300
Subject: [PATCH 2/2] Get CPU cycles on RISC-V
This test acquires CPU cycles to perform output calculations
and get timestamps. There is no cpu_cycles() implementation on RISC-V arch.
This patch gets cycles using perf events.
One of the most notable reasons to use perf event instead of
reading counter registers is to avoid modifying MUCOUNTEREN
register. Due to the RISC-V ISA specification (riscv-privileged-v1.9)
before getting any access to counter registers it is necessary to enable it in MUCOUNTEREN in a privileged mode. On the other hand,
perf events are free to use.
This patch is tested on the SiFive HiFive Unmatched board.
Signed-off-by: v.v.mitrofanov <[email protected]>
---
src/get_clock.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
src/get_clock.h | 9 +++++++
2 files changed, 71 insertions(+)
diff --git a/src/get_clock.c b/src/get_clock.c
index 78ad865..c6adbdc 100755
--- a/src/get_clock.c
+++ b/src/get_clock.c
@@ -237,3 +237,65 @@ double get_cpu_mhz(int no_cpu_freq_warn)
return proc;
#endif
}
+
+#if defined(__riscv)
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <linux/perf_event.h>
+#include <asm/unistd.h>
+
+static long perf_event_open(struct perf_event_attr *hw_event,
+ pid_t pid, int cpu, int group_fd,
+ unsigned long flags)
+{
+ return syscall(__NR_perf_event_open, hw_event, pid,
+ cpu, group_fd, flags);
+}
+
+cycles_t perf_get_cycles()
+{
+ cycles_t cycles = 0;
+ struct perf_event_attr pe;
+ const pid_t pid = 0; // Current task
+ const int cpu = -1; // On any CPU
+ const int group_fd = -1; // Use leader group
+ const unsigned long flags = 0;
+ /* Use this variable just to open perf event here and once.
+ It is appropriate because it touches only this function and
+ not fix other code */
+ static int is_open = 0;
+ /* Make file discriptor static just to keep it valid during
+ programm execution. It will be closed automatically when
+ test finishes. It is a hack just not to fix other part of test */
+ static int fd = -1;
+
+ if (!is_open) {
+ memset(&pe, 0, sizeof(pe));
+
+ pe.type = PERF_TYPE_HARDWARE;
+ pe.size = sizeof(pe);
+ pe.config = PERF_COUNT_HW_CPU_CYCLES;
+ pe.disabled = 0;
+ pe.exclude_kernel = 0;
+ pe.exclude_hv = 0;
+
+ fd = perf_event_open(&pe, pid, cpu, group_fd, flags);
+ if (fd == -1) {
+ fprintf(stderr, "Error opening perf event (%llx)\n", pe.config);
+ exit(EXIT_FAILURE);
+ }
+
+ is_open = 1;
+ }
+
+ if(read(fd, &cycles, sizeof(cycles)) < 0) {
+ fprintf(stderr, "Error reading perf event (%llx)\n", pe.config);
+ exit(EXIT_FAILURE);
+ }
+
+ return cycles;
+}
+#endif
diff --git a/src/get_clock.h b/src/get_clock.h
index dacbcd0..97c3500 100755
--- a/src/get_clock.h
+++ b/src/get_clock.h
@@ -104,6 +104,15 @@ static inline cycles_t get_cycles()
asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
return cval;
}
+#elif defined(__riscv)
+typedef unsigned long cycles_t;
+
+cycles_t perf_get_cycles();
+
+static inline cycles_t get_cycles()
+{
+ return perf_get_cycles();
+}
#elif defined(__loongarch64)
typedef unsigned long cycles_t;
--
2.40.1
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/cxh269/perftest.git
[email protected]:cxh269/perftest.git
cxh269
perftest
perftest
master

搜索帮助