| // Copyright 2017 Google Inc. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include "absl/random/internal/nanobenchmark.h" | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include "absl/base/config.h" | |
| #include "absl/log/check.h" | |
| #include "absl/log/log.h" | |
| #include "absl/strings/numbers.h" | |
| #include "absl/strings/str_format.h" | |
| namespace absl { | |
| ABSL_NAMESPACE_BEGIN | |
| namespace random_internal_nanobenchmark { | |
| namespace { | |
| uint64_t Div(const void*, FuncInput in) { | |
| // Here we're measuring the throughput because benchmark invocations are | |
| // independent. | |
| const int64_t d1 = 0xFFFFFFFFFFll / int64_t(in); // IDIV | |
| return d1; | |
| } | |
| template <size_t N> | |
| void MeasureDiv(const FuncInput (&inputs)[N]) { | |
| Result results[N]; | |
| Params params; | |
| params.max_evals = 6; // avoid test timeout | |
| const size_t num_results = Measure(&Div, nullptr, inputs, N, results, params); | |
| if (num_results == 0) { | |
| LOG(WARNING) | |
| << "WARNING: Measurement failed, should not happen when using " | |
| "PinThreadToCPU unless the region to measure takes > 1 second."; | |
| return; | |
| } | |
| for (size_t i = 0; i < num_results; ++i) { | |
| LOG(INFO) << absl::StreamFormat("%5u: %6.2f ticks; MAD=%4.2f%%\n", | |
| results[i].input, results[i].ticks, | |
| results[i].variability * 100.0); | |
| CHECK_NE(results[i].ticks, 0.0f) << "Zero duration"; | |
| } | |
| } | |
| void RunAll(const int argc, char* argv[]) { | |
| // Avoid migrating between cores - important on multi-socket systems. | |
| int cpu = -1; | |
| if (argc == 2) { | |
| if (!absl::SimpleAtoi(argv[1], &cpu)) { | |
| LOG(FATAL) << "The optional argument must be a CPU number >= 0."; | |
| } | |
| } | |
| PinThreadToCPU(cpu); | |
| // unpredictable == 1 but the compiler doesn't know that. | |
| const FuncInput unpredictable = argc != 999; | |
| static const FuncInput inputs[] = {unpredictable * 10, unpredictable * 100}; | |
| MeasureDiv(inputs); | |
| } | |
| } // namespace | |
| } // namespace random_internal_nanobenchmark | |
| ABSL_NAMESPACE_END | |
| } // namespace absl | |
| int main(int argc, char* argv[]) { | |
| absl::random_internal_nanobenchmark::RunAll(argc, argv); | |
| return 0; | |
| } |