JDK-6868976 : Sequester os_solaris.cpp'max_hrtime to its own cache line
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: solaris
  • CPU: generic
  • Submitted: 2009-08-06
  • Updated: 2014-12-10
  • Resolved: 2014-06-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Relates :  
Description
os_solaris.cpp'max_hrtime can become very hot -- placing it on its own cache line (and aligning to a 64-bit boundary on x86) should reduce interference wrt other data in the vicinity and improve performance.

Comments
Should we decide to isolate os_solaris.cpp:max_hrtime on its own cache line sometime in the future, that code would look something like this: $ hg diff src/os/solaris/vm/os_solaris.cpp diff -r 35e222a277ba src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Mon Dec 08 00:15:55 2014 -0800 +++ b/src/os/solaris/vm/os_solaris.cpp Tue Dec 09 17:00:09 2014 -0700 @@ -351,7 +351,14 @@ julong os::physical_memory() { static hrtime_t first_hrtime = 0; static const hrtime_t hrtime_hz = 1000*1000*1000; -static volatile hrtime_t max_hrtime = 0; +struct SharedGlobals { + char _pad_prefix[DEFAULT_CACHE_LINE_SIZE]; + // Hot RW variable -- Sequester to avoid false-sharing + volatile hrtime_t max_hrtime; + DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile hrtime_t)); +}; + +static SharedGlobals GVars; void os::Solaris::initialize_system_info() { @@ -1366,11 +1373,13 @@ void* os::thread_local_storage_at(int in // are forced to add a check here. inline hrtime_t getTimeNanos() { const hrtime_t now = gethrtime(); - const hrtime_t prev = max_hrtime; + const hrtime_t prev = GVars.max_hrtime; if (now <= prev) { return prev; // same or retrograde time; } - const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev); + const hrtime_t obsv = Atomic::cmpxchg(now, + (volatile jlong*)&GVars.max_hrtime, + prev); assert(obsv >= prev, "invariant"); // Monotonicity // If the CAS succeeded then we're done and return "now". // If the CAS failed and the observed value "obsv" is >= now then @@ -4534,7 +4543,7 @@ void os::init(void) { void os::init(void) { _initial_pid = getpid(); - max_hrtime = first_hrtime = gethrtime(); + GVars.max_hrtime = first_hrtime = gethrtime(); init_random(1234567);
10-12-2014

The issue described in this bug where addressed with the fix of JDK-8040140
04-06-2014

There have been two changes to the code that reduced the cache line contention for max_hrtime. The most significant change is JDK-8040140 https://bugs.openjdk.java.net/browse/JDK-8040140 This change removed the need for max_hrtime_lock variable. Since max_hrtime_lock probably shared the same cache line as max_hrtime, removing it removed contention from the same cache line as max_hrtime. The change also removed support for oldgetTimeNanos() that was used for older architectures that did not support cx8. oldgetTimeNanos() called Atomic::cmpxchg() within a for loop that also increased contention. Staffan provided detailed performance testing that showed improved performance after the change. Another related change was JDK-6784100 https://bugs.openjdk.java.net/browse/JDK-6784100 This change reduced the coherency traffic related to max_hrtime by removing a while loop that could introduce multiple Atomic::cmpxchg() calls using max_hrtime. Support for cx8 features on all solaris platforms and the two changes mentioned above has removed the need for max_hrtime to be moved to its own cache line.
04-06-2014