-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pass StringRef by value in comparison operators #2875
Conversation
The link shows what each function compiles to independently, but it doesn't show the practical result of calling them when they are inlined. Since the StringRef comparators are defined in the header and short, I would expect them to almost always be inlined, and I would also expect that the inlined and optimized final assembly would be effectively the same for both parameter versions. I could be wrong, but if so then basically to avoid this const reference overhead for small types every template class or function that takes |
Here's another Godbolt link showing what happens when you call compare1 vs compare2. The compiled assembly is effectively the same as I suspected. Only the labels have changed. Side-by-Side diff:
|
Another godbolt, this time with a for loop, just in case calling it in a pass-through style causes it to do something different: https://godbolt.org/z/DrhB7q The mystery deepens. I have a tree microbenchmark here: Which is the first commit in: https://github.com/apple/foundationdb/pull/2882/commits I wonder if anything will show up there. |
Good idea. Again only the labels have changed.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless there is microbenchmark evidence that this change is having an effect, which would mean we have use cases which are not being inlined, I am not in favor of merging it.
Also, if there are cases that are not being inlined, we should probably find out why and make them inline-able if possible. For example, calling a StringRef comparator via a pointer to member function would not be inlined but might also be avoidable.
Apologies for the radio silence on this and thanks for closing. I was also experimenting with a more broad change but couldn't convince myself that it would help or hurt performance. I still think that it is good hygiene to consistently pass small types like this by value, but I couldn't convince myself it was worth the churn. |
Because
StringRef
is small (sizeof(StringRef) == 12
), it can be efficiently passed in registers. Unfortunately, when passing by reference, theStringRef
variable has to have address, which leads to the members needing to be loaded from memory inside the function. The difference is small, but in one profile I have, > 25% of CPU time on a storage server is spent insideoperator<()
.On my r5d.2xl, the
operator<()
change led to a ~1.5% increase in TPS in the mako benchmark. I changed the other operators just for consistency.Obligatory GodBolt link: https://godbolt.org/z/Gswzfd