ordo-one / package-benchmark

Swift benchmark runner with many performance metrics and great CI support
Apache License 2.0
286 stars 19 forks source link

Measure Swift exclusivity checking overhead #255

Open jcavar opened 1 month ago

jcavar commented 1 month ago

Hello,

As we briefly touched on here, I wanted to add support for Swift's exclusivity checking metrics.

Unfortunately, swift_beginAccess and swift_endAccess are in the TEXT section of the binary:

(lldb) image lookup -s swift_beginAccess
1 symbols match 'swift_beginAccess' in /usr/lib/swift/libswiftCore.dylib:
        Address: libswiftCore.dylib[0x00000001904a9008] (libswiftCore.dylib.__TEXT.__text + 3820208)
        Summary: libswiftCore.dylib`swift_beginAccess

This section is not writable, so it is not as easy to hook this as e.g. _swift_release, which is in AUTH section:

(lldb) image lookup -s _swift_release
1 symbols match '_swift_release' in /usr/lib/swift/libswiftCore.dylib:
        Address: libswiftCore.dylib[0x00000001e87c7510] (libswiftCore.dylib.__AUTH.__data + 64320)
        Summary: _swift_release

There are a few options I am aware of that can make this work:

  1. DYLD_INTERPOSE - This is quite elegant, but DYLD_INTERPOSE needs to be loaded in a separate dylib as it needs to register first (I believe this is true, but my understanding of it is not complete)
  2. fishhook - We can dynamically swap symbols without the need for additional dylib, but this requires us to introduce an additional dependency to the project
  3. dyld_dynamic_interpose - I haven't used this, but it seems like it could be best tradeoff

Linux is an additional problem that I have no idea how to address.

Interested to hear your thoughts about it!

hassila commented 3 weeks ago

We are already interposing the memory allocator with jemalloc, which works cross platforms - a similar small library which also exposes a statistics query api could possibly work - the problem would be that it may have quite significant overhead so we'd only want to preload it if the relevant metrics are enabled. Now we run the actual benchmark as a separate process, so we can probably decide to interpose there...

jcavar commented 2 weeks ago

Can you please help me understand how jemalloc interposing works? I can't find any extra configuration in the project. Does it rely on the fact that jemalloc will be linked before libc and therefore get preference?

hassila commented 2 weeks ago

Yeah, that's correct.

jcavar commented 1 week ago

Hmm, I am not sure if it will work, considering the shared library cache, but I will give it a go.