Centos 7, 400x slower for System.nanoTime than windows
Asked Answered
P

1

9

I have seen and read posts on why System.nanoTime() is slower on some OSes than others, however I have never seen anything to explain the difference I am seeing now. Using JMH, I am running this benchmark. (Note: it uses System.nanoTime() as well)

@Benchmark
public long systemNanoTime() {
    return System.nanoTime();
}

On Windows 10, this takes ~25 ns.

On Centos 7, Linux 3.10 it is measured as taking ~10293 ns.

This is on the same machine, Intel(R) Core(TM) i7-7820X CPU @ 3.60GHz

Is there an option to change the way the JDK gets the system clock?


EDIT: Based on the link provided by Todd, it appear that tsc is not available

# more /sys/devices/system/clocksource/clocksource0/*
::::::::::::::
/sys/devices/system/clocksource/clocksource0/available_clocksource
::::::::::::::
hpet acpi_pm 
::::::::::::::
/sys/devices/system/clocksource/clocksource0/current_clocksource
::::::::::::::
hpet

after performing

echo acpi_pm > /sys/devices/system/clocksource/clocksource0/current_clocksource

The latency improved, but is still poor with a latency of 1,816 ns.

I have tried to find out if the TSC clock source can be added to Centos, but not luck yet.


EDIT: Digging a little further

# dmesg | grep -i tsc
[    0.000000] tsc: Detected 3600.000 MHz processor
[    0.058602] TSC deadline timer enabled
[    0.065868] TSC synchronization [CPU#0 -> CPU#1]:
[    0.065870] Measured 679995254538 cycles TSC warp between CPUs, turning off TSC clock.
[    0.065874] tsc: Marking TSC unstable due to check_tsc_sync_source failed
[  125.451480] Override clocksource tsc is not HRT compatible. Cannot switch while in HRT/NOHZ mode
Proclitic answered 21/8, 2017 at 18:31 Comment(2)
Have you checked out this blog post? It describes some of what you see and seems well researched. pzemtsov.github.io/2017/07/23/the-slow-currenttimemillis.htmlEinkorn
Seems like a firmware bug. I think I saw tsc synchronization patches in newer kernels (like 4.10).Convertite
P
6

Based on @apangin's suggestion I followed this page on adding the alternative repository for centos with the latest version

http://elrepo.org/tiki/tiki-index.php

and then followed the further instructions here

https://www.tecmint.com/install-upgrade-kernel-version-in-centos-7/

after installing and rebooting

# $ dmesg | grep -i tsc
[    0.001000] tsc: Detected 3600.000 MHz processor
[    0.001000] [Firmware Bug]: TSC ADJUST: CPU0: -2100392876408 force to 0
[    0.046075] TSC deadline timer enabled
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU1: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU2: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU3: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU4: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU5: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU6: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU7: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU8: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU9: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU10: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU11: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU12: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU13: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU14: 0
[    0.001000] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2100392876408 CPU15: 0
[    1.337843] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x6c1bafbc2ab, max_idle_ns: 881591058496 ns
[    2.353636] clocksource: Switched to clocksource tsc

suggesting the kernel is adjusting for a firmware bug.

Running the test again, I get an average latency of 40 ns using System.nanoTime() which is a 260 fold improvement. It also means that benchmarks using this measure are more meaningful.

Proclitic answered 22/8, 2017 at 7:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.