Index: MicroBenchmarks/MemFunctions/main.cpp =================================================================== --- MicroBenchmarks/MemFunctions/main.cpp +++ MicroBenchmarks/MemFunctions/main.cpp @@ -18,10 +18,17 @@ //===----------------------------------------------------------------------===// #include +#include +#include #include #include "benchmark/benchmark.h" +// This calls the real memcmp to check the reuslts. +int RealMemCmp(const char* p, const char* q, size_t s) __attribute__((no_builtin("memcmp"))) { + return memcmp(p, q, s); +} + // Benchmarks `memcmp(p, q, size) OP 0` where n is known at compile time and OP // is defined by `Pred`. The compiler typically inlines the memcmp + comparion // to loads and compares. @@ -44,6 +51,13 @@ for (int i = 0; i < kNumElements; ++i) Mod().template Change(p + i * kSize); + // First check the validity of the results. + if (Pred()(RealMemCmp(p, q, kSize)) != Pred()(memcmp(p, q, kSize))) { + std::cerr << "invalid results for Pred=" << Pred::kDisplay << " Mod=" << Mod::kDisplay << " kSize=" << kSize << std::endl; + std::exit(1); + } + + benchmark::DoNotOptimize(p); benchmark::DoNotOptimize(q); @@ -52,7 +66,7 @@ benchmark::ClobberMemory(); for (int i = 0; i < kNumElements; ++i) { - int res = Pred()(memcmp(p + i * kSize, q + i * kSize, kSize)); + bool res = Pred()(memcmp(p + i * kSize, q + i * kSize, kSize)); benchmark::DoNotOptimize(res); } } @@ -62,36 +76,43 @@ // Predicates. struct EqZero { bool operator()(int v) const { return v == 0; } + inline static constexpr const char kDisplay[] = "EqZero"; }; struct LessThanZero { bool operator()(int v) const { return v < 0; } + inline static constexpr const char kDisplay[] = "LessThanZero"; }; struct GreaterThanZero { bool operator()(int v) const { return v > 0; } + inline static constexpr const char kDisplay[] = "GreaterThanZero"; }; // Functors to change the first/mid/last or no value. struct None { template void Change(char* const p) const {} + inline static constexpr const char kDisplay[] = "None"; }; struct First { template void Change(char* const p) const { - p[0] = 128; + p[0] = 0xff; } + inline static constexpr const char kDisplay[] = "First"; }; struct Mid { template void Change(char* const p) const { - p[kSize / 2] = 128; + p[kSize / 2] = 0xff; } + inline static constexpr const char kDisplay[] = "Mid"; }; struct Last { template void Change(char* const p) const { - p[kSize - 1] = 128; + p[kSize - 1] = 0xff; } + inline static constexpr const char kDisplay[] = "Last"; }; #define MEMCMP_BENCHMARK_PRED_CHANGE(size, pred, change) \