Skip to content

Commit 7a233b8

Browse files
committed
Add park sleep related options and CPU util caculation code
Enable sleep in park on X86 and Power. Default sleep configuration is set based on experiments done using restCrud on Quarkus with wrk as the load generator. With the current default configuration, we observed: - ~20% throughput improvement on RHEL9 (Intel Skylake) - ~8% improvement on RHEL10 (Intel Raptor Lake) - ~11% improvement on pLinux Depends on eclipse-omr/omr#8039 Signed-off-by: Gengchen Tuo <gengchen.tuo@ibm.com>
1 parent abcfa42 commit 7a233b8

File tree

4 files changed

+81
-2
lines changed

4 files changed

+81
-2
lines changed

runtime/oti/j9nonbuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6562,6 +6562,13 @@ typedef struct J9JavaVM {
65626562
#endif /* JAVA_SPEC_VERSION >= 24 */
65636563
UDATA disclaimableRAMSegmentCount;
65646564
UDATA disclaimableROMSegmentCount;
6565+
#if defined(OMR_THR_YIELD_ALG)
6566+
omrthread_t cpuUtilCalcThread;
6567+
UDATA cpuUtilCacheInterval;
6568+
int64_t prevProcCPUTime;
6569+
int64_t prevProcTimestamp;
6570+
omrthread_monitor_t cpuUtilCacheMutex;
6571+
#endif /* defined(OMR_THR_YIELD_ALG) */
65656572
} J9JavaVM;
65666573

65676574
#define J9JFR_SAMPLER_STATE_UNINITIALIZED 0

runtime/vm/jvminit.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,9 @@ freeJavaVM(J9JavaVM * vm)
718718
omrthread_monitor_destroy(vm->globalHotFieldPoolMutex);
719719
}
720720
}
721+
#if defined(OMR_THR_YIELD_ALG)
722+
omrthread_monitor_destroy(vm->cpuUtilCacheMutex);
723+
#endif /* defined(OMR_THR_YIELD_ALG) */
721724

722725
if (NULL != vm->classMemorySegments) {
723726
J9ClassWalkState classWalkState;
@@ -7822,6 +7825,9 @@ protectedInitializeJavaVM(J9PortLibrary* portLibrary, void * userData)
78227825
}
78237826
}
78247827
#endif /* defined(J9VM_OPT_JFR) */
7828+
#if defined(OMR_THR_YIELD_ALG)
7829+
omrthread_monitor_init_with_name(&vm->cpuUtilCacheMutex, 0, "CPU Utilization Cache Mutex");
7830+
#endif /* defined(OMR_THR_YIELD_ALG) */
78257831

78267832
if (JNI_OK != (stageRC = runInitializationStage(vm, ALL_VM_ARGS_CONSUMED))) {
78277833
goto error;

runtime/vm/threadhelp.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,42 @@ timeCompensationHelper(J9VMThread *vmThread, U_8 threadHelperType, omrthread_mon
467467
}
468468
continueTimeCompensation:
469469
#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */
470+
#if defined(OMR_THR_YIELD_ALG)
471+
static UDATA parkPolicy = **(UDATA **)omrthread_global((char *)"parkPolicy");
472+
if (2 == parkPolicy) {
473+
J9JavaVM *vm = vmThread->javaVM;
474+
PORT_ACCESS_FROM_JAVAVM(vm);
475+
int64_t currentTime = j9time_nano_time();
476+
omrthread_process_time_t currentProcCPUTimes = {0};
477+
static const uintptr_t numberOfCpus = j9sysinfo_get_number_CPUs_by_type(J9PORT_CPU_BOUND);
478+
479+
if (-1 == vm->prevProcTimestamp) {
480+
intptr_t processTimeRC = omrthread_get_process_times(&currentProcCPUTimes);
481+
if (0 == processTimeRC) {
482+
if (omrthread_monitor_try_enter(vm->cpuUtilCacheMutex)) {
483+
vm->prevProcCPUTime = currentProcCPUTimes._userTime + currentProcCPUTimes._systemTime;
484+
vm->prevProcTimestamp = currentTime;
485+
}
486+
}
487+
} else {
488+
UDATA timeDelta = currentTime - vm->prevProcTimestamp;
489+
if (timeDelta >= vm->cpuUtilCacheInterval * 1000000000){
490+
intptr_t processTimeRC = omrthread_get_process_times(&currentProcCPUTimes);
491+
if (0 == processTimeRC) {
492+
if (omrthread_monitor_try_enter(vm->cpuUtilCacheMutex)) {
493+
double timeElapsedAllCores = (double)numberOfCpus * timeDelta;
494+
double util = (currentProcCPUTimes._systemTime + currentProcCPUTimes._userTime - vm->prevProcCPUTime) / timeElapsedAllCores * 100;
495+
496+
**(UDATA **)omrthread_global((char *)"cpuUtilCache") = (UDATA)util;
497+
498+
vm->prevProcCPUTime = currentProcCPUTimes._userTime + currentProcCPUTimes._systemTime;
499+
vm->prevProcTimestamp = currentTime;
500+
}
501+
}
502+
}
503+
}
504+
}
505+
#endif /* defined(OMR_THR_YIELD_ALG) */
470506

471507
switch(threadHelperType) {
472508
/* Following three APIs return J9THREAD_TIMED_OUT when the timeout expired.

runtime/vm/vmthread.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,11 +739,23 @@ threadParseArguments(J9JavaVM *vm, char *optArg)
739739

740740

741741
#if defined(OMR_THR_YIELD_ALG)
742+
#if defined(J9VM_ARCH_X86) || defined(J9VM_ARCH_POWER)
743+
**(UDATA **)omrthread_global((char *)"parkPolicy") = 2;
744+
#else
742745
**(UDATA **)omrthread_global((char *)"parkPolicy") = 0;
746+
#endif
743747
**(UDATA **)omrthread_global((char *)"parkSleepMultiplier") = 0;
744-
**(UDATA **)omrthread_global((char *)"parkSleepTime") = 0;
748+
**(UDATA **)omrthread_global((char *)"parkSleepTime") = 400;
745749
**(UDATA **)omrthread_global((char *)"parkSpinCount") = 0;
746-
**(UDATA **)omrthread_global((char *)"parkSleepCount") = 0;
750+
**(UDATA **)omrthread_global((char *)"parkSleepCount") = 2;
751+
#if defined(J9VM_ARCH_POWER)
752+
**(UDATA **)omrthread_global((char *)"parkSleepCpuUtilThreshold") = 99;
753+
#elif defined(J9VM_ARCH_X86) /* defined(OMR_ARCH_POWER) */
754+
**(UDATA **)omrthread_global((char *)"parkSleepCpuUtilThreshold") = 80;
755+
#else /* defined(J9VM_ARCH_X86) */
756+
**(UDATA **)omrthread_global((char *)"parkSleepCpuUtilThreshold") = 100;
757+
#endif /* defined(J9VM_ARCH_X86) */
758+
vm->cpuUtilCacheInterval = 5;
747759
#endif /* defined(OMR_THR_YIELD_ALG) */
748760

749761
/* parse arguments */
@@ -1352,6 +1364,24 @@ threadParseArguments(J9JavaVM *vm, char *optArg)
13521364
**(UDATA **)omrthread_global((char *)"parkSleepCount") = parkSleepCount;
13531365
continue;
13541366
}
1367+
1368+
if (try_scan(&scan_start, "cpuUtilCacheInterval=")) {
1369+
UDATA cacheInterval = 0;
1370+
if (scan_udata(&scan_start, &cacheInterval)) {
1371+
goto _error;
1372+
}
1373+
vm->cpuUtilCacheInterval = cacheInterval;
1374+
continue;
1375+
}
1376+
1377+
if (try_scan(&scan_start, "parkSleepCpuUtilThreshold=")) {
1378+
UDATA threshold = 0;
1379+
if (scan_udata(&scan_start, &threshold)) {
1380+
goto _error;
1381+
}
1382+
**(UDATA **)omrthread_global((char *)"parkSleepCpuUtilThreshold") = threshold;
1383+
continue;
1384+
}
13551385
#endif /* defined(OMR_THR_YIELD_ALG) */
13561386

13571387
/* Couldn't find a match for arguments */

0 commit comments

Comments
 (0)