代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/perftest 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。