Live data from Hacker News

A 40-line fix eliminated a 400x performance gap

questdb.com

51–60 of 81 posts

Re: A 40-line fix eliminated a 400x performance gap

#51
post #17

You can do even faster, about 8ns (almost an additional 10x improvement) by using software perf events: PERF_COUNT_SW_TASK_CLOCK is thread CPU time, it can be read through a shared page (so no syscall, see perf_event_mmap_page), and then you add the delta since the last context switch with a single rdtsc call within a seqlock. This is not well documented unfortunately, and I'm not aware of open-source implementations…

[deleted]

Re: A 40-line fix eliminated a 400x performance gap

#53
Author of the OpenJDK patch here.

Thanks for the write-up Jaromir :) For those interested, I explored memory overhead when reading /proc—including eBPF profiling and the history behind the poorly documented user-space ABI.

Full details in my write-up: https://norlinder.nu/posts/User-CPU-Time-JVM/

Re: A 40-line fix eliminated a 400x performance gap

#54
post #19

Earlier quoted context omitted.

Yes you need some lazy setup in thread-local state to use this. And short-lived threads should be avoided anyway :)

I guess if you need the concurrency/throughput you should use a userspace green thread implementation. I’m guessing most implementations of green threads multiplex onto long running os threads anyway

In a system with green threads, you typically want the CPU time of the fiber or tasklet rather than the carrier thread. In that case, you have to ask the scheduler, not the kernel.

Re: A 40-line fix eliminated a 400x performance gap

#55
post #17

You can do even faster, about 8ns (almost an additional 10x improvement) by using software perf events: PERF_COUNT_SW_TASK_CLOCK is thread CPU time, it can be read through a shared page (so no syscall, see perf_event_mmap_page), and then you add the delta since the last context switch with a single rdtsc call within a seqlock. This is not well documented unfortunately, and I'm not aware of open-source implementations…

Why do you need a seqlock? To make sure you're not context switched out between the read of the page value and the rdtsc?

Presumably you mean you just double check the page value after the rdtsc to make sure it hasn't changed and retry if it has?

Tbh I thought clock_gettime was a vdso based virtual syscall anyway

Re: A 40-line fix eliminated a 400x performance gap

#56
post #53

Author of the OpenJDK patch here. Thanks for the write-up Jaromir :) For those interested, I explored memory overhead when reading /proc—including eBPF profiling and the history behind the poorly documented user-space ABI. Full details in my write-up: https://norlinder.nu/posts/User-CPU-Time-JVM/

Hi Jonas, thanks for the work on OpenJDK and the post! I swear I hadn't seen your blog :) I finished my draft around Christmas and it’s been in the queue since. Great minds think alike, I guess.

edit: I just read your blog in full and I have to say I like it more than mine. You put a lot more rigor into it. I’m just peeking into things.

edit2: I linked your article from my post.

Re: A 40-line fix eliminated a 400x performance gap

#57

Flamegraphs are wonderful. Me: looks at my code. "sure, ok, looks alright." Me: looks at the resulting flamegraph. "what the hell is this?!?!?" I've found all kinds of crazy stuff in codebases this way. Static initializers that aren't static, one-line logger calls that trigger expensive serialization, heavy string-parsing calls that don't memoize patterns, etc. Unfortunately some of those are my fault.

I've never used flamegraphs but would like to know about them. Can you explain more? Or where should I start?

I would also try hotspot, it is a interactive viewer for perf graphs.

Re: A 40-line fix eliminated a 400x performance gap

#59
post #46
post #29

Earlier quoted context omitted.

I also like icicle graphs for this. They're flamegraphs, but aggregated in the reverse order. (I.e. if you have calls A->B->C and D->E->C, then both calls to C are aggregated together, rather than being stacked on top of B and E respectively. It can make it easier to see what's wrong when you have a bunch of distinct codepaths that all invoke a common library where you're spending too much time.) Regular flamegraphs…

So someone else linked the original flamegraph site [0] and it describes icicle graphs as "inverting the y axis" but that's not only what's happening, right? You bucket top-down the stack opposed to bottom-up, correct? [0] https://www.brendangregg.com/flamegraphs.html

Right, what is needed is something trie-like, with the root being the most fine-grained call.

Re: A 40-line fix eliminated a 400x performance gap

#60
post #41

Earlier quoted context omitted.

You don't actually know that for sure. You have only placed a new upper bound.

This seems like more of a philosophical argument than a practical one.

No, it is a very practical one and I'm actually surprised that you don't see it that way. Benchmarking is hard, and if you don't understand the basics then you can easily measure nonsense.
Post reply on HN