Skip to content
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

Force inline boost::gregorian::date::date(special_values) to improve performance #122

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

p12tic
Copy link
Contributor

@p12tic p12tic commented Feb 3, 2020

Fixes #121

A small overview of benefits and potential downsides is extracted from #121 below:

This compiler workaround would improve the code size and speed for the majority of user workloads that are affected.

The only possibility this could be a regression would be in rarely executed call sites that pass non-constant value of special_values directly or indirectly to boost::gregorian::date::date. However, forcing inlining in such a case would just inflate code size a little bit and I suspect that the library user would still save code size overall due to significant reductions of code size around calls to default constructor of ptime and related types.

In my case the performance of whole application has been improved by around 5%.

At least GCC 6.5.0, 7.4.0 and 8.3.0 fail to inline
gregorian::date::date(special_values) when constructing
posix_time::ptime and possibly other types. This leads to large
performance overheads for a operation that should ideally be a store of
a constant to some memory location.
@p12tic p12tic force-pushed the forceinline-gregorian-date-special-values-constructor branch from b861d0e to 0c7c332 Compare February 3, 2020 21:27
@codecov
Copy link

codecov bot commented Feb 4, 2020

Codecov Report

Merging #122 into develop will decrease coverage by 0.08%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #122      +/-   ##
===========================================
- Coverage    53.41%   53.33%   -0.09%     
===========================================
  Files           83       83              
  Lines         4944     4933      -11     
  Branches      2407     2397      -10     
===========================================
- Hits          2641     2631      -10     
  Misses         420      420              
+ Partials      1883     1882       -1
Impacted Files Coverage Δ
include/boost/date_time/gregorian/greg_date.hpp 59.45% <100%> (-8.11%) ⬇️
...de/boost/date_time/local_time/custom_time_zone.hpp 37.93% <0%> (-2.07%) ⬇️
...oost/date_time/posix_time/posix_time_legacy_io.hpp 75.51% <0%> (-0.97%) ⬇️
...ude/boost/date_time/local_time/posix_time_zone.hpp 30.4% <0%> (-0.81%) ⬇️
...lude/boost/date_time/posix_time/time_serialize.hpp 28.35% <0%> (-0.63%) ⬇️
include/boost/date_time/time_facet.hpp 35.77% <0%> (+0.09%) ⬆️
...clude/boost/date_time/gregorian/greg_serialize.hpp 43.38% <0%> (+0.62%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 061aec8...0c7c332. Read the comment docs.

@JeffGarland JeffGarland self-assigned this Feb 11, 2020
Copy link
Collaborator

@JeffGarland JeffGarland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So as much as I can see using the FORCEINLINE, I'm wondering if with this function we shouldn't just write good old 'inline' -- I suspect that will work fine on all modern compilers and is more pleasing that yet another macro.

@p12tic
Copy link
Contributor Author

p12tic commented Feb 11, 2020

This function is already inline by being defined within the body of the class definition. inline does not tell the compiler anything about the actual inlining behaviour, it just makes the linker accept multiple definitions of the function. Thus BOOST_FORCEINLINE is essentially the only option.

To verify in this particular case, I've tested inline on GCC 7.4.0 and it doesn't force inlining.

@p12tic
Copy link
Contributor Author

p12tic commented Mar 1, 2020

@JeffGarland Ping. Issues like this is what created bad opinion about Boost libraries in certain circles where performance is important :(

@JeffGarland
Copy link
Collaborator

I really don't want to have a bad attitude on this change, but I'm not convinced it's the best way -- force inline seems like a non-standard hack -- I'd like to get out of that business. See my comment in the other issue about constexpr seems like that's the correct approach.

Oh, I could really care less about what the performance oriented folks want -- I work for free on my spare time -- which means not on anyone else's timeline, sorry. If people really want performance they are free to hack the code as you have and otherwise.

@p12tic
Copy link
Contributor Author

p12tic commented Mar 2, 2020

I'm sorry if I made it look like I expect free work from you, that's not the case. My point was that these issues are important to a certain subset of developers.

Regarding constexpr, I agree that it would be the best solution. Unfortunately it does not seem to be enough in this case. I marked all functions involved in the constructor code path as constexpr and I still see the same problem.

I believe that if there turn out to be no better alternatives, BOOST_FORCEINLINE would be justified to apply in this case. It speeds up date_time library as a whole several times. There are already more than 2 thousands uses of BOOST_FORCEINLINE throughout the boost libraries. The date_time library itself already uses plenty of per-compiler code paths.

@JeffGarland
Copy link
Collaborator

JeffGarland commented Mar 2, 2020

Of course you want me to do work :) I was only triggered by: "Issues like this is what created bad opinion...". I'm sure no matter what I did someone won't be happy. Some have moved to Howard's library bc the fundamental design (no special values) makes things faster.

Do you have the changes with the constexpr on a branch somewhere - I'd be curious to see that. Also, you're testing mostly with g++7.4? Presumably with at least std=c++14?

@jeking3
Copy link
Contributor

jeking3 commented Sep 30, 2020

Quite interesting to see the effect on code coverage from that one change...

@p12tic
Copy link
Contributor Author

p12tic commented Jul 31, 2022

PR #214 is a better solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Default-constructing boost::posix_time::ptime and possibly other types is slow
3 participants