Parse the decimal128 max significand at compile time - #1480
Merged
Merged
Conversation
- max_significand_v() for decimal128 returned the _u128 literal. fenv_round_impl calls it at run time, thus each rounding up parsed 34 digits. - The function now keeps the literal in a constexpr variable, thus the compiler parses it. - decimal128 addition is 1.36x faster and tan is 1.29x faster. Multiplication, division and decimal64 do not change.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1480 +/- ##
=========================================
+ Coverage 98.6% 98.6% +0.1%
=========================================
Files 312 312
Lines 26265 26266 +1
Branches 2264 2264
=========================================
+ Hits 25892 25893 +1
Misses 373 373
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
For decimal128,
max_significand_v()returns the_u128literal of 34 nines. When it rounds up,fenv_round_implcalls this function at run time, thus each call parses 34 digits. This PR keeps the literal in a localconstexprvariable, thus the compiler parses it. Decimal128 addition is 1.36 times faster andtanis 1.29 times faster.Cause
fenv_rounding.hpplines 602 and 606 callmax_significand_v<TargetType>()in a normal expression, not in a constant expression. Thus the compiler can evaluateoperator""_u128at run time.-O2,from_chars_integer_impltakes 7% of the time of a loop of decimal128tan. Half of it comes fromtan, and half from the+=in the loop._u128literals are inconstexprtables, thus the compiler parses them.Speed
Google Benchmark, median of 9 runs, 1024 random operands with 34 or 16 digits, GCC 16.2.1 at
-O3:Multiplication, division and decimal64 do not change, as expected.
Tests
runtests pass.test_format_fmtlibdoes not build on develop either (thechar32_tsign conversion infmt_format.hpp).test_fenv,test_cmath,test_trig_rounding,test_sqrt_rounding,test_decimal_quantumandtest_big_uintspass.