gcc/libstdc++-v3/testsuite
Cassio Neri 126793971b libstdc++: More efficient is_leap
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.
2021-02-24 18:25:18 +00:00
..
17_intro libstdc++: Fix failing tests due to 'u' identifier in kernel header 2021-02-24 16:34:05 +00:00
18_support
19_diagnostics libstdc++: Fix incorrect test for std::error_code comparisons 2021-02-03 15:49:36 +00:00
20_util libstdc++: Robustify long double std::to_chars testcase [PR98384] 2021-02-24 12:24:43 -05:00
21_strings libstdc++: Fix up constexpr std::char_traits<char>::compare [PR99181] 2021-02-23 09:30:18 +01:00
22_locale
23_containers libstdc++: Add unordered containers heterogeneous lookup 2021-02-09 21:56:27 +01:00
24_iterators
25_algorithms
26_numerics
27_io libstdc++: Fix filesystem::rename on Windows [PR 98985] 2021-02-12 15:29:50 +00:00
28_regex
29_atomics libstdc++-v3: Add -fcf-protection=none to -march=i486 2021-01-15 17:37:20 -08:00
30_threads libstdc++: XFAIL tests that depends on RTTI 2021-02-12 14:30:13 +00:00
abi
backward
config
data
decimal
experimental libstdc++: Fix filesystem::rename on Windows [PR 98985] 2021-02-12 15:29:50 +00:00
ext libstdc++: Suppress more vstring testsuite warnings. [PR 98613] 2021-01-10 18:22:51 -05:00
lib
libstdc++-abi
libstdc++-dg libstdc++: Add std::experimental::simd from the Parallelism TS 2 2021-01-27 16:37:26 +00:00
libstdc++-prettyprinters
libstdc++-xmethods
performance
special_functions
std libstdc++: More efficient is_leap 2021-02-24 18:25:18 +00:00
tr1
tr2
util libstdc++: Restore <unistd.h> in testsuite_fs.h header [PR 99096] 2021-02-14 20:38:32 +00:00
Makefile.am libstdc++: Work around test failures using -mno-tree-vrp 2021-02-03 15:49:30 +00:00
Makefile.in libstdc++: Work around test failures using -mno-tree-vrp 2021-02-03 15:49:30 +00:00