3 ms·
FWIW, I get very different results from inside my Linux VM (MacBook Pro, 2.9 GHz Core i7): jit: 1.433856 ns/call plt: 1.700611 ns/call ind: 1.40439
by nneonneo 8y ago
FWIW, I get very different results from inside my Linux VM (MacBook Pro, 2.9 GHz Core i7):
jit: 1.433856 ns/call
plt: 1.700611 ns/call
ind: 1.404397 ns/call
The PLT is double-indirected (call->jmp->func), but the single-indirect call performs the same as the JIT. This backs up @tlb's note that modern x86 machines will predict indirect calls.
- vardump 8y agoWhich CPU you got? Lots of MacBook Pros have 2.9 GHz i7, ranging from 2012 to 2018 models.
- nneonneo 8y agoIt's a MacBookPro14,3, which makes it an i7-7820HQ according to everymac.
- glandium 8y agoSee https://news.ycombinator.com/item?id=17165535 https://news.ycombinator.com/item?id=17165535
- nneonneo 8y agoNow that I'm thinking about it a bit more - I recall that GCC 6.1 added "-fno-plt" for x64 targets, which replaces PLT calls with "call [func@got]" instead, eliminating the double-indirection. Unfortunately, I don't have a GCC 6.1 environment, so I'd be curious to see if someone can run the benchmark with "-fno-plt" and how it performs. A combination of that plus indirect call prediction should basically close the gap with the JIT approach.
- glandium 8y agoSee this thread from yesterday: https://news.ycombinator.com/item?id=17165448 https://news.ycombinator.com/item?id=17165448 tl;dr: getting the function address first with dlsym or using -fno-plt does close the gap.
- damien 8y agoIt does close the gap. Before: cc -shared -fPIC -Os -s -o empty.so empty.c cc -std=c99 -Wall -Wextra -O3 -g3 -fpie -pie -o benchmark benchmark.c ./empty.so -ldl jit: 1.541608 ns/call plt: 2.309939 ns/call ind: 1.540583 ns/call After: cc -shared -fPIC -Os -s -o empty.so empty.c cc -std=c99 -Wall -Wextra -O3 -g3 -fpie -fno-plt -pie -o benchmark benchmark.c ./empty.so -ldl jit: 1.541836 ns/call plt: 1.539239 ns/call ind: 1.542874 ns/call