brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · 6df0187 Raw
214 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11#include <array>12#include <format>13#include <random>14 15#include "../CartesianBenchmarks.h"16#include "benchmark/benchmark.h"17#include "test_macros.h"18 19// Tests the full range of the value.20template <class T>21static std::array<T, 1000> generate(std::uniform_int_distribution<T> distribution = std::uniform_int_distribution<T>{22                                        std::numeric_limits<T>::min(), std::numeric_limits<T>::max()}) {23  std::mt19937 generator;24  std::array<T, 1000> result;25  std::generate_n(result.begin(), result.size(), [&] { return distribution(generator); });26  return result;27}28 29template <class T>30static void BM_Basic(benchmark::State& state) {31  std::array data{generate<T>()};32  std::array<char, 100> output;33 34  while (state.KeepRunningBatch(data.size()))35    for (auto value : data)36      benchmark::DoNotOptimize(std::format_to(output.begin(), "{}", value));37}38BENCHMARK(BM_Basic<uint32_t>);39BENCHMARK(BM_Basic<int32_t>);40BENCHMARK(BM_Basic<uint64_t>);41BENCHMARK(BM_Basic<int64_t>);42 43// Ideally the low values of a 128-bit value are all dispatched to a 64-bit routine.44#ifndef TEST_HAS_NO_INT12845template <class T>46static void BM_BasicLow(benchmark::State& state) {47  using U = std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>;48  std::array data{49      generate<T>(std::uniform_int_distribution<T>{std::numeric_limits<U>::min(), std::numeric_limits<U>::max()})};50  std::array<char, 100> output;51 52  while (state.KeepRunningBatch(data.size()))53    for (auto value : data)54      benchmark::DoNotOptimize(std::format_to(output.begin(), "{}", value));55}56BENCHMARK(BM_BasicLow<__uint128_t>);57BENCHMARK(BM_BasicLow<__int128_t>);58 59BENCHMARK(BM_Basic<__uint128_t>);60BENCHMARK(BM_Basic<__int128_t>);61#endif62 63// *** Localization ***64enum class LocalizationE { False, True };65struct AllLocalizations : EnumValuesAsTuple<AllLocalizations, LocalizationE, 2> {66  static constexpr const char* Names[] = {"LocFalse", "LocTrue"};67};68 69template <LocalizationE E>70struct Localization {};71 72template <>73struct Localization<LocalizationE::False> {74  static constexpr const char* fmt = "";75};76 77template <>78struct Localization<LocalizationE::True> {79  static constexpr const char* fmt = "L";80};81 82// *** Base ***83enum class BaseE {84  Binary,85  Octal,86  Decimal,87  Hex,88  HexUpper,89};90struct AllBases : EnumValuesAsTuple<AllBases, BaseE, 5> {91  static constexpr const char* Names[] = {"BaseBin", "BaseOct", "BaseDec", "BaseHex", "BaseHexUpper"};92};93 94template <BaseE E>95struct Base {};96 97template <>98struct Base<BaseE::Binary> {99  static constexpr const char* fmt = "b";100};101 102template <>103struct Base<BaseE::Octal> {104  static constexpr const char* fmt = "o";105};106 107template <>108struct Base<BaseE::Decimal> {109  static constexpr const char* fmt = "d";110};111 112template <>113struct Base<BaseE::Hex> {114  static constexpr const char* fmt = "x";115};116 117template <>118struct Base<BaseE::HexUpper> {119  static constexpr const char* fmt = "X";120};121 122// *** Types ***123enum class TypeE { Int64, Uint64 };124struct AllTypes : EnumValuesAsTuple<AllTypes, TypeE, 2> {125  static constexpr const char* Names[] = {"Int64", "Uint64"};126};127 128template <TypeE E>129struct Type {};130 131template <>132struct Type<TypeE::Int64> {133  using type = int64_t;134 135  static std::array<type, 1000> make_data() { return generate<type>(); }136};137 138template <>139struct Type<TypeE::Uint64> {140  using type = uint64_t;141 142  static std::array<type, 1000> make_data() { return generate<type>(); }143};144 145// *** Alignment ***146enum class AlignmentE { None, Left, Center, Right, ZeroPadding };147struct AllAlignments : EnumValuesAsTuple<AllAlignments, AlignmentE, 5> {148  static constexpr const char* Names[] = {149      "AlignNone", "AlignmentLeft", "AlignmentCenter", "AlignmentRight", "ZeroPadding"};150};151 152template <AlignmentE E>153struct Alignment {};154 155template <>156struct Alignment<AlignmentE::None> {157  static constexpr const char* fmt = "";158};159 160template <>161struct Alignment<AlignmentE::Left> {162  static constexpr const char* fmt = "0<512";163};164 165template <>166struct Alignment<AlignmentE::Center> {167  static constexpr const char* fmt = "0^512";168};169 170template <>171struct Alignment<AlignmentE::Right> {172  static constexpr const char* fmt = "0>512";173};174 175template <>176struct Alignment<AlignmentE::ZeroPadding> {177  static constexpr const char* fmt = "0512";178};179 180template <class L, class B, class T, class A>181struct Integral {182  void run(benchmark::State& state) const {183    std::array data{Type<T::value>::make_data()};184    std::array<char, 512> output;185 186    while (state.KeepRunningBatch(data.size()))187      for (auto value : data)188        benchmark::DoNotOptimize(std::format_to(output.begin(), std::string_view{fmt.data(), fmt.size()}, value));189  }190 191  std::string name() const { return "Integral" + L::name() + B::name() + A::name() + T::name(); }192 193  static constexpr std::string make_fmt() {194    return std::string("{:") + Alignment<A::value>::fmt + Localization<L::value>::fmt + Base<B::value>::fmt + "}";195  }196 197  static constexpr auto fmt = []() {198    constexpr size_t s = make_fmt().size();199    std::array<char, s> r;200    std::ranges::copy(make_fmt(), r.begin());201    return r;202  }();203};204 205int main(int argc, char** argv) {206  benchmark::Initialize(&argc, argv);207  if (benchmark::ReportUnrecognizedArguments(argc, argv))208    return 1;209 210  makeCartesianProductBenchmark<Integral, AllLocalizations, AllBases, AllTypes, AllAlignments>();211 212  benchmark::RunSpecifiedBenchmarks();213}214