This is an automated email from the ASF dual-hosted git repository.
chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git
The following commit(s) were added to refs/heads/master by this push:
new 956227b0 cputime optimize for arm64 (#3247)
956227b0 is described below
commit 956227b077246a93ca1c36bb4d55844b478f49a8
Author: dwh110 <[email protected]>
AuthorDate: Thu Aug 6 14:09:21 2026 +0800
cputime optimize for arm64 (#3247)
* cputime optimize for arm64
Update src/butil/time.cpp
modify using __attribute__((constructor)) and merge
init_invariant_cpu_freq to inside function read_invariant_cpu_frequency
* Add the macro switch BUTIL_USE_CPU_FREQUENCY while preserving the
original default behavior for ARM64
* 1、Activation options: CMake -DWITH_CPU_FREQUENCY=ON, Bazel --define
BUTIL_USE_CPU_FREQUENCY=true, script argument --with-cpu-frequency.
2、Disabled by default for consistent legacy behavior.
* fix compile failed
---------
Co-authored-by: seekdwh <[email protected]>
---
BUILD.bazel | 13 ++++++++++++-
CMakeLists.txt | 9 +++++++++
bazel/config/BUILD.bazel | 6 ++++++
config.h.in | 5 +++++
config_brpc.sh | 11 +++++++++--
example/BUILD.bazel | 3 +++
src/butil/time.cpp | 12 +++++++++---
src/butil/time.h | 15 ++++++---------
8 files changed, 59 insertions(+), 15 deletions(-)
diff --git a/BUILD.bazel b/BUILD.bazel
index 5dc5fcf7..b1676c4a 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -60,7 +60,10 @@ DEFINES = [
}) + select({
"//bazel/config:brpc_with_no_pthread_mutex_hook":
["NO_PTHREAD_MUTEX_HOOK"],
"//conditions:default": [],
- })
+ }) + select({
+ "//bazel/config:brpc_with_cpu_frequency": ["BUTIL_USE_CPU_FREQUENCY=1"],
+ "//conditions:default": ["BUTIL_USE_CPU_FREQUENCY=0"],
+})
LINKOPTS = [
"-pthread",
@@ -116,6 +119,14 @@ genrule(
"//conditions:default": "0",
}) +
"""
+#ifdef BUTIL_USE_CPU_FREQUENCY
+#undef BUTIL_USE_CPU_FREQUENCY
+#endif
+#define BUTIL_USE_CPU_FREQUENCY """ + select({
+ "//bazel/config:brpc_with_cpu_frequency": "1",
+ "//conditions:default": "0",
+ }) +
+ """
#endif // BUTIL_CONFIG_H
EOF
""",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 915b7d29..2b92dca1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,6 +30,7 @@ option(WITH_RDMA "With RDMA" OFF)
option(WITH_UBRING "With UB" OFF)
option(WITH_DEBUG_BTHREAD_SCHE_SAFETY "With debugging bthread sche safety" OFF)
option(WITH_DEBUG_LOCK "With debugging lock" OFF)
+option(WITH_CPU_FREQUENCY "Use CPU frequency for cpuwide_time" OFF)
option(WITH_ASAN "With AddressSanitizer" OFF)
option(BUILD_UNIT_TESTS "Whether to build unit tests" OFF)
option(BUILD_FUZZ_TESTS "Whether to build fuzz tests" OFF)
@@ -76,6 +77,12 @@ if(WITH_GLOG)
set(BRPC_WITH_GLOG 1)
endif()
+set(WITH_CPU_FREQUENCY_VAL "0")
+if(WITH_CPU_FREQUENCY)
+ set(WITH_CPU_FREQUENCY_VAL "1")
+ set(BUTIL_USE_CPU_FREQUENCY 1)
+endif()
+
if(WITH_DEBUG_SYMBOLS)
list(APPEND BRPC_COMMON_COMPILE_OPTIONS -g)
endif()
@@ -156,6 +163,7 @@ list(APPEND BRPC_COMMON_DEFINITIONS
BRPC_WITH_UBRING=${WITH_UBRING_VAL}
BRPC_DEBUG_BTHREAD_SCHE_SAFETY=${WITH_DEBUG_BTHREAD_SCHE_SAFETY_VAL}
BRPC_DEBUG_LOCK=${WITH_DEBUG_LOCK_VAL}
+ BUTIL_USE_CPU_FREQUENCY=${WITH_CPU_FREQUENCY_VAL}
BTHREAD_USE_FAST_PTHREAD_MUTEX
__const__=__unused__
_GNU_SOURCE
@@ -166,6 +174,7 @@ list(APPEND BRPC_COMMON_DEFINITIONS
__STDC_CONSTANT_MACROS
__STRICT_ANSI__
)
+
if(NOT DEBUG)
list(APPEND BRPC_COMMON_DEFINITIONS NDEBUG)
endif()
diff --git a/bazel/config/BUILD.bazel b/bazel/config/BUILD.bazel
index eec551da..fabc4be0 100644
--- a/bazel/config/BUILD.bazel
+++ b/bazel/config/BUILD.bazel
@@ -36,6 +36,12 @@ config_setting(
define_values = {"BRPC_WITH_GLOG": "true"},
)
+config_setting(
+ name = "brpc_with_cpu_frequency",
+ define_values = {"BUTIL_USE_CPU_FREQUENCY": "true"},
+ visibility = ["//visibility:public"],
+)
+
selects.config_setting_group(
name = "brpc_with_mesalink",
match_any = [
diff --git a/config.h.in b/config.h.in
index 4f26e577..d8de111b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -21,4 +21,9 @@
#endif
#cmakedefine BRPC_WITH_GLOG @WITH_GLOG_VAL@
+#ifdef BUTIL_USE_CPU_FREQUENCY
+#undef BUTIL_USE_CPU_FREQUENCY
+#endif
+#cmakedefine BUTIL_USE_CPU_FREQUENCY @WITH_CPU_FREQUENCY_VAL@
+
#endif // BUTIL_CONFIG_H
diff --git a/config_brpc.sh b/config_brpc.sh
index 1c059420..3237d663 100755
--- a/config_brpc.sh
+++ b/config_brpc.sh
@@ -54,7 +54,7 @@ else
LDD=ldd
fi
-TEMP=`getopt -o v: --long
headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-rdma,with-mesalink,with-bthread-tracer,with-debug-bthread-sche-safety,with-debug-lock,with-asan,with-riscv-zvbc,with-riscv-zbc,nodebugsymbols,werror
-n 'config_brpc' -- "$@"`
+TEMP=`getopt -o v: --long
headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-rdma,with-mesalink,with-bthread-tracer,with-debug-bthread-sche-safety,with-debug-lock,with-asan,with-riscv-zvbc,with-riscv-zbc,with-cpu-frequency,nodebugsymbols,werror
-n 'config_brpc' -- "$@"`
WITH_GLOG=0
WITH_THRIFT=0
WITH_RDMA=0
@@ -67,6 +67,7 @@ BRPC_DEBUG_BTHREAD_SCHE_SAFETY=0
DEBUGSYMBOLS=-g
WERROR=
BRPC_DEBUG_LOCK=0
+WITH_CPU_FREQUENCY=0
if [ $? != 0 ] ; then >&2 $ECHO "Terminating..."; exit 1 ; fi
@@ -93,6 +94,7 @@ while true; do
--with-bthread-tracer) WITH_BTHREAD_TRACER=1; shift 1 ;;
--with-debug-bthread-sche-safety ) BRPC_DEBUG_BTHREAD_SCHE_SAFETY=1;
shift 1 ;;
--with-debug-lock ) BRPC_DEBUG_LOCK=1; shift 1 ;;
+ --with-cpu-frequency ) WITH_CPU_FREQUENCY=1; shift 1 ;;
--with-asan) WITH_ASAN=1; shift 1 ;;
--with-riscv-zvbc) WITH_RISCV_ZVBC=1; shift 1 ;;
--with-riscv-zbc) WITH_RISCV_ZBC=1; shift 1 ;;
@@ -479,7 +481,7 @@ append_to_output "STATIC_LINKINGS=$STATIC_LINKINGS"
append_to_output "DYNAMIC_LINKINGS=$DYNAMIC_LINKINGS"
# CPP means C PreProcessing, not C PlusPlus
-CPPFLAGS="${CPPFLAGS} -DBRPC_WITH_GLOG=$WITH_GLOG
-DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=$BRPC_DEBUG_BTHREAD_SCHE_SAFETY
-DBRPC_DEBUG_LOCK=$BRPC_DEBUG_LOCK"
+CPPFLAGS="${CPPFLAGS} -DBRPC_WITH_GLOG=$WITH_GLOG
-DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=$BRPC_DEBUG_BTHREAD_SCHE_SAFETY
-DBRPC_DEBUG_LOCK=$BRPC_DEBUG_LOCK
-DBUTIL_USE_CPU_FREQUENCY=$WITH_CPU_FREQUENCY"
# Avoid over-optimizations of TLS variables by GCC>=4.8
# See: https://github.com/apache/brpc/issues/1693
@@ -649,6 +651,11 @@ cat << EOF > src/butil/config.h
#endif
#define BRPC_WITH_GLOG $WITH_GLOG
+#ifdef BUTIL_USE_CPU_FREQUENCY
+#undef BUTIL_USE_CPU_FREQUENCY
+#endif
+#define BUTIL_USE_CPU_FREQUENCY $WITH_CPU_FREQUENCY
+
#endif // BUTIL_CONFIG_H
EOF
diff --git a/example/BUILD.bazel b/example/BUILD.bazel
index 4ee7cb14..d0115dc4 100644
--- a/example/BUILD.bazel
+++ b/example/BUILD.bazel
@@ -31,6 +31,9 @@ COPTS = [
] + select({
"//bazel/config:brpc_with_glog": ["-DBRPC_WITH_GLOG=1"],
"//conditions:default": ["-DBRPC_WITH_GLOG=0"],
+}) + select({
+ "//bazel/config:brpc_with_cpu_frequency": ["-DBUTIL_USE_CPU_FREQUENCY=1"],
+ "//conditions:default": ["-DBUTIL_USE_CPU_FREQUENCY=0"],
}) + select({
"//bazel/config:brpc_with_rdma": ["-DBRPC_WITH_RDMA=1"],
"//conditions:default": [""],
diff --git a/src/butil/time.cpp b/src/butil/time.cpp
index 2c726d9b..ad91831f 100644
--- a/src/butil/time.cpp
+++ b/src/butil/time.cpp
@@ -143,16 +143,22 @@ int64_t read_cpu_frequency(bool* invariant_tsc) {
}
// Return value must be >= 0
-int64_t read_invariant_cpu_frequency() {
+static int64_t read_invariant_cpu_frequency() {
bool invariant_tsc = false;
- const int64_t freq = read_cpu_frequency(&invariant_tsc);
+ int64_t freq = -1;
+#if defined(__aarch64__) && BUTIL_USE_CPU_FREQUENCY
+ __asm__ __volatile__("mrs %0, CNTFRQ_EL0" : "=r"(freq));
+#else
+ freq = read_cpu_frequency(&invariant_tsc);
if (!invariant_tsc || freq < 0) {
return 0;
}
+#endif
+
return freq;
}
-int64_t invariant_cpu_freq = -1;
+int64_t invariant_cpu_freq = read_invariant_cpu_frequency();
} // namespace detail
} // namespace butil
diff --git a/src/butil/time.h b/src/butil/time.h
index c57000ea..d0daaa5f 100644
--- a/src/butil/time.h
+++ b/src/butil/time.h
@@ -265,10 +265,12 @@ inline uint64_t clock_cycles() {
#error "unsupported arch"
#endif
}
-extern int64_t read_invariant_cpu_frequency();
+
// Be positive iff:
// 1 Intel x86_64 CPU (multiple cores) supporting constant_tsc and
// nonstop_tsc(check flags in /proc/cpuinfo)
+// 2 aarch64, where the counter frequency is read from CNTFRQ_EL0.
+// Only computed when BUTIL_USE_CPU_FREQUENCY is enabled.
extern int64_t invariant_cpu_freq;
} // namespace detail
@@ -279,7 +281,7 @@ extern int64_t invariant_cpu_freq;
// note: Inlining shortens time cost per-call for 15ns in a loop of many
// calls to this function.
inline int64_t cpuwide_time_ns() {
-#if !defined(BAIDU_INTERNAL)
+#if !defined(BAIDU_INTERNAL) && !BUTIL_USE_CPU_FREQUENCY
// nearly impossible to get the correct invariant cpu frequency on
// different CPU and machines. CPU-ID rarely works and frequencies
// in "model name" and "cpu Mhz" are both unreliable.
@@ -298,16 +300,11 @@ inline int64_t cpuwide_time_ns() {
const uint64_t remain = tsc % cpu_freq;
// TODO: should be OK until CPU's frequency exceeds 16GHz.
return remain * 1000000000L / cpu_freq + sec * 1000000000L;
- } else if (!cpu_freq) {
+ } else {
// Lack of necessary features, return system-wide monotonic time
instead.
return monotonic_time_ns();
- } else {
- // Use a thread-unsafe method(OK to us) to initialize the freq
- // to save a "if" test comparing to using a local static variable
- detail::invariant_cpu_freq = detail::read_invariant_cpu_frequency();
- return cpuwide_time_ns();
}
-#endif // defined(BAIDU_INTERNAL)
+#endif // defined(BAIDU_INTERNAL) || BUTIL_USE_CPU_FREQUENCY
}
// Get cpu clock time of the current thread in nanoseconds without the time
spent in blocking I/O operations.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]