Add fast nanosecond-resolution per-thread CPU timer#9811
Open
mszabo-wikia wants to merge 1 commit into
Open
Conversation
The HHVM JIT is heavily instrumented via scoped `WorkloadStats` structs
that call `Timer::GetThreadCPUTimeNanos` to obtain the CPU timer of
the current thread. This then calls `fb_perf_get_thread_cputime_ns`
in internal Meta builds but falls back to `folly::chrono::clock_gettime_ns`
in our OSS build which just wraps `clock_gettime`.
It seems there was an abortive attempt in 2013 to upstream a kernel patch
for a fast VDSO implementation of `clock_gettime_ns`, after which
`fb_perf_get_thread_cputime_ns` was added to provide a similarly performant
nanosecond-resolution timer for the current thread's CPU time using the `perf_events` API.[2]
This never made its way into OSS.
We observed the Folly shim to be responsible for 30-40% of CPU usage during
JIT compilation while executing warmup code. After rolling out a change
disabling it, we saw a double-digit P99 reduction across background jobs
latencies and a ~30% increase in deployment speed.
So, try to implement (with some AI assistance) an API-compatible `fb_perf_get_thread_cputime_ns`
implementation backed by `perf_events` that can be used by HHVM OSS.
On my machine, this is 67x faster than the folly shim:
```
vagrant@hhvm-jammy-vm:~/hhvm$ _build/hphp/util/test/hphp_util_bench --bm_mode=adaptive
E20260618 19:12:04.745777 15497 BenchmarkAdaptive.cpp:549] Did not converge:
folly_clock_gettime_ns: p33.30=132.3ns to 0.13%, 1025 samples, 1s
[unstable] 1st=132.76 [132.54, 133.15] 2nd=132.07 [131.97, 132.12]
============================================================================
[...]p/util/test/perf-cputime-ns-bench.cpp relative time/iter iters/s
============================================================================
folly_clock_gettime_ns 132.26ns 7.56M
perf_get_thread_cputime_ns 6760.1% 1.96ns 511.12M
```
[1] https://lore.kernel.org/all/5226FAE1.5070201@fb.com/
[2] facebook@28e6bf1
Contributor
|
This pull request has been imported. If you are a Meta employee, you can view this in D111476887. (Because this pull request was imported automatically, there will not be any future comments.) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The HHVM JIT is heavily instrumented via scoped
WorkloadStatsstructs that callTimer::GetThreadCPUTimeNanosto obtain the CPU timer of the current thread. This then callsfb_perf_get_thread_cputime_nsin internal Meta builds but falls back tofolly::chrono::clock_gettime_nsin our OSS build which just wrapsclock_gettime.It seems there was an abortive attempt in 2013 to upstream a kernel patch for a fast VDSO implementation of
clock_gettime_ns, after whichfb_perf_get_thread_cputime_nswas added to provide a similarly performant nanosecond-resolution timer for the current thread's CPU time using theperf_eventsAPI.[2] This never made its way into OSS.We observed the Folly shim to be responsible for 30-40% of CPU usage during JIT compilation while executing warmup code. After rolling out a change disabling it, we saw a double-digit P99 reduction across background jobs latencies and a ~30% increase in deployment speed. So, try to implement (with some AI assistance) an API-compatible
fb_perf_get_thread_cputime_nsimplementation backed byperf_eventsthat can be used by HHVM OSS.On my machine, this is 67x faster than the folly shim:
[1] https://lore.kernel.org/all/5226FAE1.5070201@fb.com/
[2] 28e6bf1