mirror of
https://github.com/redis/redis.git
synced 2026-02-03 20:39:54 -05:00
Enable hardware clock by default on ARM AArch64. (#14676)
Some checks are pending
CI / test-ubuntu-latest (push) Waiting to run
CI / test-sanitizer-address (push) Waiting to run
CI / build-debian-old (push) Waiting to run
CI / build-macos-latest (push) Waiting to run
CI / build-32bit (push) Waiting to run
CI / build-libc-malloc (push) Waiting to run
CI / build-centos-jemalloc (push) Waiting to run
CI / build-old-chain-jemalloc (push) Waiting to run
Codecov / code-coverage (push) Waiting to run
External Server Tests / test-external-standalone (push) Waiting to run
External Server Tests / test-external-cluster (push) Waiting to run
External Server Tests / test-external-nodebug (push) Waiting to run
Spellcheck / Spellcheck (push) Waiting to run
Some checks are pending
CI / test-ubuntu-latest (push) Waiting to run
CI / test-sanitizer-address (push) Waiting to run
CI / build-debian-old (push) Waiting to run
CI / build-macos-latest (push) Waiting to run
CI / build-32bit (push) Waiting to run
CI / build-libc-malloc (push) Waiting to run
CI / build-centos-jemalloc (push) Waiting to run
CI / build-old-chain-jemalloc (push) Waiting to run
Codecov / code-coverage (push) Waiting to run
External Server Tests / test-external-standalone (push) Waiting to run
External Server Tests / test-external-cluster (push) Waiting to run
External Server Tests / test-external-nodebug (push) Waiting to run
Spellcheck / Spellcheck (push) Waiting to run
Redis can already use a processor-provided hardware counter as a high-performance monotonic clock. On some architectures this must be enabled carefully, but on ARM AArch64 the situation is different: - The ARM Generic Timer is architecturally mandatory for all processors that implement the AArch64 execution state. - The system counter (`CNTVCT_EL0`) and its frequency (`CNTFRQ_EL0`) are guaranteed to exist and provide a monotonic time source (per the *“The Generic Timer in AArch64 state”* section of the *Arm® Architecture Reference Manual for Armv8-A* — https://developer.arm.com/documentation/ddi0487/latest). Because of this architectural guarantee, it is safe to enable the hardware clock by default on ARM AArch64. Like detailed bellow, this gives us around 5% boost on io-thread deployments for a simple strings benchmark.
This commit is contained in:
parent
60a4fa2e4b
commit
3c96680cfb
2 changed files with 19 additions and 7 deletions
|
|
@ -882,7 +882,9 @@ make MALLOC=jemalloc
|
|||
|
||||
By default, Redis will build using the POSIX clock_gettime function as the monotonic clock source. On most modern systems, the internal processor clock can be used to improve performance. Cautions can be found here: http://oliveryang.net/2015/09/pitfalls-of-TSC-usage/
|
||||
|
||||
To build with support for the processor's internal instruction clock, use:
|
||||
On ARM aarch64 systems, the hardware clock is enabled by default because the ARM Generic Timer is architecturally guaranteed to be available and monotonic on all ARMv8-A processors (see the *“The Generic Timer in AArch64 state”* section of the *Arm Architecture Reference Manual for Armv8-A*).
|
||||
|
||||
To build with support for the processor's internal instruction clock on other architectures, use:
|
||||
|
||||
```sh
|
||||
make CFLAGS="-DUSE_PROCESSOR_CLOCK"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,13 @@ static char monotonic_info_string[32];
|
|||
* generally safe on modern systems, this link provides additional information
|
||||
* about use of the x86 TSC: http://oliveryang.net/2015/09/pitfalls-of-TSC-usage
|
||||
*
|
||||
* To use the processor clock, either uncomment this line, or build with
|
||||
* On ARM aarch64 systems, the hardware clock is enabled by default because the
|
||||
* ARM Generic Timer is architecturally guaranteed to be available and monotonic
|
||||
* on all ARMv8-A processors (see the “The Generic Timer in AArch64 state”
|
||||
* section of the Arm Architecture Reference Manual for Armv8-A).
|
||||
*
|
||||
* To use the processor clock on other architectures, either uncomment this line,
|
||||
* or build with
|
||||
* CFLAGS="-DUSE_PROCESSOR_CLOCK"
|
||||
#define USE_PROCESSOR_CLOCK
|
||||
*/
|
||||
|
|
@ -92,18 +98,22 @@ static void monotonicInit_x86linux(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(USE_PROCESSOR_CLOCK) && defined(__aarch64__)
|
||||
#if defined(__aarch64__)
|
||||
static long mono_ticksPerMicrosecond = 0;
|
||||
|
||||
/* Read the clock value. */
|
||||
/* Read the clock value.
|
||||
* CNTVCT_EL0 is a system counter register, that provides the monotonic
|
||||
* timestamp as a 64-bit count value. */
|
||||
static inline uint64_t __cntvct(void) {
|
||||
uint64_t virtual_timer_value;
|
||||
__asm__ volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
|
||||
return virtual_timer_value;
|
||||
}
|
||||
|
||||
/* Read the Count-timer Frequency. */
|
||||
/* Read the Count-timer Frequency.
|
||||
* CNTFRQ_EL0 is a system counter register that provides the frequency (in Hz)
|
||||
* needed to convert ticks to microseconds. Together with CNTVCT_EL0, this enables
|
||||
* high-performance monotonic time measurement without system calls. */
|
||||
static inline uint32_t cntfrq_hz(void) {
|
||||
uint64_t virtual_freq_value;
|
||||
__asm__ volatile("mrs %0, cntfrq_el0" : "=r"(virtual_freq_value));
|
||||
|
|
@ -213,7 +223,7 @@ const char * monotonicInit(void) {
|
|||
if (getMonotonicUs == NULL) monotonicInit_x86linux();
|
||||
#endif
|
||||
|
||||
#if defined(USE_PROCESSOR_CLOCK) && defined(__aarch64__)
|
||||
#if defined(__aarch64__)
|
||||
if (getMonotonicUs == NULL) monotonicInit_aarch64();
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue