126793971b
This patch reimplements std::chrono::year::is_leap(). Leap year check is ubiquitously implemented (including here) as: y % 4 == 0 && (y % 100 != 0 || y % 400 == 0). The rationale being that testing divisibility by 4 first implies an earlier return for 75% of the cases, therefore, avoiding the needless calculations of y % 100 and y % 400. Although this fact is true, it does not take into account the cost of branching. This patch, instead, tests divisibility by 100 first: (y % 100 != 0 || y % 400 == 0) && y % 4 == 0. It is certainly counterintuitive that this could be more efficient since among the three divisibility tests (4, 100 and 400) the one by 100 is the only one that can never provide a definitive answer and a second divisibility test (by 4 or 400) is always required. However, measurements [1] in x86_64 suggest this is 3x more efficient! A possible explanation is that checking divisibility by 100 first implies a split in the execution path with probabilities of (1%, 99%) rather than (25%, 75%) when divisibility by 4 is checked first. This decreases the entropy of the branching distribution which seems to help prediction. Given that y belongs to [-32767, 32767] [time.cal.year.members], a more efficient algorithm [2] to check divisibility by 100 is used (instead of y % 100 != 0). Measurements suggest that this optimization improves performance by 20%. The patch adds a test that exhaustively compares the result of this implementation with the ubiquitous one for all y in [-32767, 32767]. Although its completeness, the test completes in a matter of seconds. References: [1] https://stackoverflow.com/a/60646967/1137388 [2] https://accu.org/journals/overload/28/155/overload155.pdf#page=16 libstdc++-v3/ChangeLog: * include/std/chrono (year::is_leap): New implementation. * testsuite/std/time/year/2.cc: New test. |
||
---|---|---|
.. | ||
17_intro | ||
18_support | ||
19_diagnostics | ||
20_util | ||
21_strings | ||
22_locale | ||
23_containers | ||
24_iterators | ||
25_algorithms | ||
26_numerics | ||
27_io | ||
28_regex | ||
29_atomics | ||
30_threads | ||
abi | ||
backward | ||
config | ||
data | ||
decimal | ||
experimental | ||
ext | ||
lib | ||
libstdc++-abi | ||
libstdc++-dg | ||
libstdc++-prettyprinters | ||
libstdc++-xmethods | ||
performance | ||
special_functions | ||
std | ||
tr1 | ||
tr2 | ||
util | ||
Makefile.am | ||
Makefile.in |