Merge bitcoin/bitcoin#24852: util: optimize HexStr

5e61532e72 util: optimizes HexStr (Martin Leitner-Ankerl)
4e2b99f72a bench: Adds a benchmark for HexStr (Martin Leitner-Ankerl)
67c8411c37 test: Adds a test for HexStr that checks all 256 bytes (Martin Leitner-Ankerl)

Pull request description:

  In my benchmark, this rewrite improves runtime 27% (g++) to 46% (clang++) for the benchmark `HexStrBench`:

  g++ 11.2.0
  |             ns/byte |              byte/s |    err% |        ins/byte |        cyc/byte |    IPC |       bra/byte |   miss% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
  |                0.94 |    1,061,381,310.36 |    0.7% |           12.00 |            3.01 |  3.990 |           1.00 |    0.0% |      0.01 | `HexStrBench` master
  |                0.68 |    1,465,366,544.25 |    1.7% |            6.00 |            2.16 |  2.778 |           1.00 |    0.0% |      0.01 | `HexStrBench` branch

  clang++ 13.0.1
  |             ns/byte |              byte/s |    err% |        ins/byte |        cyc/byte |    IPC |       bra/byte |   miss% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
  |                0.80 |    1,244,713,415.92 |    0.9% |           10.00 |            2.56 |  3.913 |           0.50 |    0.0% |      0.01 | `HexStrBench` master
  |                0.43 |    2,324,188,940.72 |    0.2% |            4.00 |            1.37 |  2.914 |           0.25 |    0.0% |      0.01 | `HexStrBench` branch

  Note that the idea for this change comes from denis2342 in #23364. This is a rewrite so no unaligned accesses occur.

  Also, the lookup table is now calculated at compile time, which hopefully makes the code a bit easier to review.

ACKs for top commit:
  laanwj:
    Code review ACK 5e61532e72
  aureleoules:
    tACK 5e61532e72.
  theStack:
    ACK 5e61532e72 🚤

Tree-SHA512: 40b53d5908332473ef24918d3a80ad1292b60566c02585fa548eb4c3189754971be5a70325f4968fce6d714df898b52d9357aba14d4753a8c70e6ffd273a2319
This commit is contained in:
laanwj
2022-05-04 20:19:51 +02:00
4 changed files with 64 additions and 6 deletions

View File

@@ -198,6 +198,24 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
BOOST_CHECK_EQUAL(HexStr(in_s), out_exp);
BOOST_CHECK_EQUAL(HexStr(in_b), out_exp);
}
{
auto input = std::string();
for (size_t i=0; i<256; ++i) {
input.push_back(static_cast<char>(i));
}
auto hex = HexStr(input);
BOOST_TEST_REQUIRE(hex.size() == 512);
static constexpr auto hexmap = std::string_view("0123456789abcdef");
for (size_t i = 0; i < 256; ++i) {
auto upper = hexmap.find(hex[i * 2]);
auto lower = hexmap.find(hex[i * 2 + 1]);
BOOST_TEST_REQUIRE(upper != std::string_view::npos);
BOOST_TEST_REQUIRE(lower != std::string_view::npos);
BOOST_TEST_REQUIRE(i == upper*16 + lower);
}
}
}
BOOST_AUTO_TEST_CASE(span_write_bytes)