Messages in this thread | | | From | Dmitry Vyukov <> | Date | Thu, 9 Jun 2022 14:28:08 +0200 | Subject | Re: [PATCH 0/8] perf/hw_breakpoint: Optimize for thousands of tasks |
| |
On Thu, 9 Jun 2022 at 13:30, Marco Elver <elver@google.com> wrote: > > The hw_breakpoint subsystem's code has seen little change in over 10 > years. In that time, systems with >100s of CPUs have become common, > along with improvements to the perf subsystem: using breakpoints on > thousands of concurrent tasks should be a supported usecase. > > The breakpoint constraints accounting algorithm is the major bottleneck > in doing so: > > 1. task_bp_pinned() has been O(#tasks), and called twice for each CPU. > > 2. Everything is serialized on a global mutex, 'nr_bp_mutex'. > > This series first optimizes task_bp_pinned() to only take O(1) on > average, and then reworks synchronization to allow concurrency when > checking and updating breakpoint constraints for tasks. Along the way, > smaller micro-optimizations and cleanups are done as they seemed obvious > when staring at the code (but likely insignificant). > > The result is (on a system with 256 CPUs) that we go from: > > | $> perf bench -r 30 breakpoint thread -b 4 -p 64 -t 64 > [ ^ more aggressive benchmark parameters took too long ] > | # Running 'breakpoint/thread' benchmark: > | # Created/joined 30 threads with 4 breakpoints and 64 parallelism > | Total time: 236.418 [sec] > | > | 123134.794271 usecs/op > | 7880626.833333 usecs/op/cpu > > ... to -- with all optimizations: > > | $> perf bench -r 30 breakpoint thread -b 4 -p 64 -t 64 > | # Running 'breakpoint/thread' benchmark: > | # Created/joined 30 threads with 4 breakpoints and 64 parallelism > | Total time: 0.071 [sec] > | > | 37.134896 usecs/op > | 2376.633333 usecs/op/cpu > > On the used test system, that's an effective speedup of ~3315x per op.
Awesome!
> Which is close to the theoretical ideal performance through > optimizations in hw_breakpoint.c -- for reference, constraints > accounting disabled: > > | perf bench -r 30 breakpoint thread -b 4 -p 64 -t 64 > | # Running 'breakpoint/thread' benchmark: > | # Created/joined 30 threads with 4 breakpoints and 64 parallelism > | Total time: 0.067 [sec] > | > | 35.286458 usecs/op > | 2258.333333 usecs/op/cpu > > At this point, the current implementation is only ~5% slower than the > theoretical ideal. However, given constraints accounting cannot > realistically be disabled, this is likely as far as we can push it. > > Marco Elver (8): > perf/hw_breakpoint: Optimize list of per-task breakpoints > perf/hw_breakpoint: Mark data __ro_after_init > perf/hw_breakpoint: Optimize constant number of breakpoint slots > perf/hw_breakpoint: Make hw_breakpoint_weight() inlinable > perf/hw_breakpoint: Remove useless code related to flexible > breakpoints > perf/hw_breakpoint: Reduce contention with large number of tasks > perf/hw_breakpoint: Optimize task_bp_pinned() if CPU-independent > perf/hw_breakpoint: Clean up headers > > arch/sh/include/asm/hw_breakpoint.h | 5 +- > arch/x86/include/asm/hw_breakpoint.h | 5 +- > include/linux/hw_breakpoint.h | 1 - > include/linux/perf_event.h | 3 +- > kernel/events/hw_breakpoint.c | 374 +++++++++++++++++++-------- > 5 files changed, 276 insertions(+), 112 deletions(-) > > -- > 2.36.1.255.ge46751e96f-goog
| |