crc32c_benchmark.cc
1 // Copyright 2017 The CRC32C Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 5 #include <cstddef> 6 #include <cstdint> 7 8 #ifdef CRC32C_HAVE_CONFIG_H 9 #include "crc32c/crc32c_config.h" 10 #endif 11 12 #include "benchmark/benchmark.h" 13 14 #if CRC32C_TESTS_BUILT_WITH_GLOG 15 #include "glog/logging.h" 16 #endif // CRC32C_TESTS_BUILT_WITH_GLOG 17 18 #include "./crc32c_arm64.h" 19 #include "./crc32c_arm64_check.h" 20 #include "./crc32c_internal.h" 21 #include "./crc32c_sse42.h" 22 #include "./crc32c_sse42_check.h" 23 #include "crc32c/crc32c.h" 24 25 class CRC32CBenchmark : public benchmark::Fixture { 26 public: 27 void SetUp(const benchmark::State& state) override { 28 block_size_ = static_cast<size_t>(state.range(0)); 29 block_data_ = std::string(block_size_, 'x'); 30 block_buffer_ = reinterpret_cast<const uint8_t*>(block_data_.data()); 31 } 32 33 protected: 34 std::string block_data_; 35 const uint8_t* block_buffer_; 36 size_t block_size_; 37 }; 38 39 BENCHMARK_DEFINE_F(CRC32CBenchmark, Public)(benchmark::State& state) { 40 uint32_t crc = 0; 41 for (auto _ : state) 42 crc = crc32c::Extend(crc, block_buffer_, block_size_); 43 state.SetBytesProcessed(state.iterations() * block_size_); 44 } 45 BENCHMARK_REGISTER_F(CRC32CBenchmark, Public) 46 ->RangeMultiplier(16) 47 ->Range(256, 16777216); // Block size. 48 49 BENCHMARK_DEFINE_F(CRC32CBenchmark, Portable)(benchmark::State& state) { 50 uint32_t crc = 0; 51 for (auto _ : state) 52 crc = crc32c::ExtendPortable(crc, block_buffer_, block_size_); 53 state.SetBytesProcessed(state.iterations() * block_size_); 54 } 55 BENCHMARK_REGISTER_F(CRC32CBenchmark, Portable) 56 ->RangeMultiplier(16) 57 ->Range(256, 16777216); // Block size. 58 59 #if HAVE_ARM64_CRC32C 60 61 BENCHMARK_DEFINE_F(CRC32CBenchmark, ArmCRC32C)(benchmark::State& state) { 62 if (!crc32c::CanUseArm64Crc32()) { 63 state.SkipWithError("ARM CRC32C instructions not available or not enabled"); 64 return; 65 } 66 67 uint32_t crc = 0; 68 for (auto _ : state) 69 crc = crc32c::ExtendArm64(crc, block_buffer_, block_size_); 70 state.SetBytesProcessed(state.iterations() * block_size_); 71 } 72 BENCHMARK_REGISTER_F(CRC32CBenchmark, ArmCRC32C) 73 ->RangeMultiplier(16) 74 ->Range(256, 16777216); // Block size. 75 76 #endif // HAVE_ARM64_CRC32C 77 78 #if HAVE_SSE42 && (defined(_M_X64) || defined(__x86_64__)) 79 80 BENCHMARK_DEFINE_F(CRC32CBenchmark, Sse42)(benchmark::State& state) { 81 if (!crc32c::CanUseSse42()) { 82 state.SkipWithError("SSE4.2 instructions not available or not enabled"); 83 return; 84 } 85 86 uint32_t crc = 0; 87 for (auto _ : state) 88 crc = crc32c::ExtendSse42(crc, block_buffer_, block_size_); 89 state.SetBytesProcessed(state.iterations() * block_size_); 90 } 91 BENCHMARK_REGISTER_F(CRC32CBenchmark, Sse42) 92 ->RangeMultiplier(16) 93 ->Range(256, 16777216); // Block size. 94 95 #endif // HAVE_SSE42 && (defined(_M_X64) || defined(__x86_64__)) 96 97 int main(int argc, char** argv) { 98 #if CRC32C_TESTS_BUILT_WITH_GLOG 99 google::InitGoogleLogging(argv[0]); 100 google::InstallFailureSignalHandler(); 101 #endif // CRC32C_TESTS_BUILT_WITH_GLOG 102 103 benchmark::Initialize(&argc, argv); 104 benchmark::RunSpecifiedBenchmarks(); 105 return 0; 106 }