* commit '479070c51e34f9f9f809df4daa8184e5b2947f14': Refactor the benchmark code.
This commit is contained in:
		@@ -20,12 +20,29 @@ LOCAL_PATH := $(call my-dir)
 | 
				
			|||||||
# Benchmarks library, usable by projects outside this directory.
 | 
					# Benchmarks library, usable by projects outside this directory.
 | 
				
			||||||
# -----------------------------------------------------------------------------
 | 
					# -----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					benchmark_cflags := \
 | 
				
			||||||
 | 
					    -O2 \
 | 
				
			||||||
 | 
					    -fno-builtin \
 | 
				
			||||||
 | 
					    -Wall \
 | 
				
			||||||
 | 
					    -Wextra \
 | 
				
			||||||
 | 
					    -Werror \
 | 
				
			||||||
 | 
					    -Wunused \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					benchmark_cppflags := \
 | 
				
			||||||
 | 
					    -std=gnu++11 \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					benchmarklib_src_files := \
 | 
				
			||||||
 | 
					    Benchmark.cpp \
 | 
				
			||||||
 | 
					    utils.cpp \
 | 
				
			||||||
 | 
					    main.cpp \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include $(CLEAR_VARS)
 | 
					include $(CLEAR_VARS)
 | 
				
			||||||
LOCAL_MODULE := libbenchmark
 | 
					LOCAL_MODULE := libbenchmark
 | 
				
			||||||
LOCAL_CFLAGS += -O2 -Wall -Wextra -Werror
 | 
					LOCAL_CFLAGS := $(benchmark_cflags)
 | 
				
			||||||
LOCAL_SRC_FILES := benchmark_main.cpp
 | 
					LOCAL_CPPFLAGS := $(benchmark_cppflags)
 | 
				
			||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 | 
					LOCAL_SRC_FILES := $(benchmarklib_src_files)
 | 
				
			||||||
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 | 
					LOCAL_C_INCLUDES := $(benchmark_c_includes)
 | 
				
			||||||
 | 
					LOCAL_STATIC_LIBRARIES := libutils
 | 
				
			||||||
include $(BUILD_STATIC_LIBRARY)
 | 
					include $(BUILD_STATIC_LIBRARY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Only supported on linux systems.
 | 
					# Only supported on linux systems.
 | 
				
			||||||
@@ -33,11 +50,12 @@ ifeq ($(HOST_OS),linux)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
include $(CLEAR_VARS)
 | 
					include $(CLEAR_VARS)
 | 
				
			||||||
LOCAL_MODULE := libbenchmark
 | 
					LOCAL_MODULE := libbenchmark
 | 
				
			||||||
LOCAL_CFLAGS += -O2 -Wall -Wextra -Werror
 | 
					LOCAL_CFLAGS := $(benchmark_cflags)
 | 
				
			||||||
LOCAL_SRC_FILES := benchmark_main.cpp
 | 
					LOCAL_CPPFLAGS := $(benchmark_cppflags)
 | 
				
			||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 | 
					LOCAL_SRC_FILES := $(benchmarklib_src_files)
 | 
				
			||||||
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 | 
					LOCAL_C_INCLUDES := $(benchmark_c_includes)
 | 
				
			||||||
LOCAL_MULTILIB := both
 | 
					LOCAL_MULTILIB := both
 | 
				
			||||||
 | 
					LOCAL_STATIC_LIBRARIES := libutils
 | 
				
			||||||
include $(BUILD_HOST_STATIC_LIBRARY)
 | 
					include $(BUILD_HOST_STATIC_LIBRARY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
@@ -45,16 +63,9 @@ endif
 | 
				
			|||||||
# -----------------------------------------------------------------------------
 | 
					# -----------------------------------------------------------------------------
 | 
				
			||||||
# Benchmarks.
 | 
					# Benchmarks.
 | 
				
			||||||
# -----------------------------------------------------------------------------
 | 
					# -----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					benchmark_src_files := \
 | 
				
			||||||
benchmark_c_flags = \
 | 
					 | 
				
			||||||
    -O2 \
 | 
					 | 
				
			||||||
    -Wall -Wextra -Wunused \
 | 
					 | 
				
			||||||
    -Werror \
 | 
					 | 
				
			||||||
    -fno-builtin \
 | 
					 | 
				
			||||||
    -std=gnu++11 \
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
benchmark_src_files = \
 | 
					 | 
				
			||||||
    math_benchmark.cpp \
 | 
					    math_benchmark.cpp \
 | 
				
			||||||
 | 
					    property_benchmark.cpp \
 | 
				
			||||||
    pthread_benchmark.cpp \
 | 
					    pthread_benchmark.cpp \
 | 
				
			||||||
    semaphore_benchmark.cpp \
 | 
					    semaphore_benchmark.cpp \
 | 
				
			||||||
    stdio_benchmark.cpp \
 | 
					    stdio_benchmark.cpp \
 | 
				
			||||||
@@ -70,9 +81,10 @@ LOCAL_MODULE := bionic-benchmarks
 | 
				
			|||||||
LOCAL_MODULE_STEM_32 := bionic-benchmarks32
 | 
					LOCAL_MODULE_STEM_32 := bionic-benchmarks32
 | 
				
			||||||
LOCAL_MODULE_STEM_64 := bionic-benchmarks64
 | 
					LOCAL_MODULE_STEM_64 := bionic-benchmarks64
 | 
				
			||||||
LOCAL_MULTILIB := both
 | 
					LOCAL_MULTILIB := both
 | 
				
			||||||
LOCAL_CFLAGS += $(benchmark_c_flags)
 | 
					LOCAL_CFLAGS := $(benchmark_cflags)
 | 
				
			||||||
LOCAL_SRC_FILES := $(benchmark_src_files) property_benchmark.cpp
 | 
					LOCAL_CPPFLAGS := $(benchmark_cppflags)
 | 
				
			||||||
LOCAL_STATIC_LIBRARIES += libbenchmark
 | 
					LOCAL_SRC_FILES := $(benchmark_src_files)
 | 
				
			||||||
 | 
					LOCAL_STATIC_LIBRARIES := libbenchmark libutils
 | 
				
			||||||
include $(BUILD_EXECUTABLE)
 | 
					include $(BUILD_EXECUTABLE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# We don't build a static benchmark executable because it's not usually
 | 
					# We don't build a static benchmark executable because it's not usually
 | 
				
			||||||
@@ -90,10 +102,11 @@ LOCAL_MODULE := bionic-benchmarks-glibc
 | 
				
			|||||||
LOCAL_MODULE_STEM_32 := bionic-benchmarks-glibc32
 | 
					LOCAL_MODULE_STEM_32 := bionic-benchmarks-glibc32
 | 
				
			||||||
LOCAL_MODULE_STEM_64 := bionic-benchmarks-glibc64
 | 
					LOCAL_MODULE_STEM_64 := bionic-benchmarks-glibc64
 | 
				
			||||||
LOCAL_MULTILIB := both
 | 
					LOCAL_MULTILIB := both
 | 
				
			||||||
LOCAL_CFLAGS += $(benchmark_c_flags)
 | 
					LOCAL_CFLAGS := $(benchmark_cflags)
 | 
				
			||||||
LOCAL_LDFLAGS += -lrt
 | 
					LOCAL_CPPFLAGS := $(benchmark_cppflags)
 | 
				
			||||||
 | 
					LOCAL_LDFLAGS := -lrt
 | 
				
			||||||
LOCAL_SRC_FILES := $(benchmark_src_files)
 | 
					LOCAL_SRC_FILES := $(benchmark_src_files)
 | 
				
			||||||
LOCAL_STATIC_LIBRARIES += libbenchmark
 | 
					LOCAL_STATIC_LIBRARIES := libbenchmark libutils
 | 
				
			||||||
include $(BUILD_HOST_EXECUTABLE)
 | 
					include $(BUILD_HOST_EXECUTABLE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										154
									
								
								benchmarks/Benchmark.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								benchmarks/Benchmark.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2012 The Android Open Source Project
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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 <inttypes.h>
 | 
				
			||||||
 | 
					#include <regex.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <utils/stringprintf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace testing {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint64_t NanoTime() {
 | 
				
			||||||
 | 
					  struct timespec t;
 | 
				
			||||||
 | 
					  t.tv_sec = t.tv_nsec = 0;
 | 
				
			||||||
 | 
					  clock_gettime(CLOCK_MONOTONIC, &t);
 | 
				
			||||||
 | 
					  return static_cast<uint64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<Benchmark*>& Benchmark::List() {
 | 
				
			||||||
 | 
					  static std::vector<Benchmark*> list;
 | 
				
			||||||
 | 
					  return list;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t Benchmark::MaxNameColumnWidth() {
 | 
				
			||||||
 | 
					  size_t max = 20;
 | 
				
			||||||
 | 
					  for (auto& benchmark : List()) {
 | 
				
			||||||
 | 
					    max = std::max(max, benchmark->NameColumnWidth());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return max;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Benchmark::RunAll(std::vector<regex_t*>& regs) {
 | 
				
			||||||
 | 
					  bool ran_benchmark = false;
 | 
				
			||||||
 | 
					  for (auto& benchmark : List()) {
 | 
				
			||||||
 | 
					    if (benchmark->ShouldRun(regs)) {
 | 
				
			||||||
 | 
					      if (!ran_benchmark) {
 | 
				
			||||||
 | 
					        printf("%-*s %10s %10s\n", MaxNameColumnWidth(), "", "iterations", "ns/op");
 | 
				
			||||||
 | 
					        ran_benchmark = true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      benchmark->RunAll();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return ran_benchmark;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Benchmark::ShouldRun(std::vector<regex_t*>& regs) {
 | 
				
			||||||
 | 
					  if (regs.empty()) {
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (const auto& re : regs) {
 | 
				
			||||||
 | 
					    if (regexec(re, Name().c_str(), 0, NULL, 0) != REG_NOMATCH) {
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Benchmark::StopBenchmarkTiming() {
 | 
				
			||||||
 | 
					  if (start_time_ns_ != 0) {
 | 
				
			||||||
 | 
					    total_time_ns_ += NanoTime() - start_time_ns_;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  start_time_ns_ = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Benchmark::StartBenchmarkTiming() {
 | 
				
			||||||
 | 
					  if (start_time_ns_ == 0) {
 | 
				
			||||||
 | 
					    start_time_ns_ = NanoTime();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string BenchmarkWithoutArg::GetNameStr(void*) {
 | 
				
			||||||
 | 
					  return Name();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <>
 | 
				
			||||||
 | 
					std::string BenchmarkWithArg<int>::GetNameStr(int arg) {
 | 
				
			||||||
 | 
					  return Name() + "/" + PrettyInt(arg, 2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <>
 | 
				
			||||||
 | 
					std::string BenchmarkWithArg<double>::GetNameStr(double arg) {
 | 
				
			||||||
 | 
					  return Name() + "/" + android::StringPrintf("%0.6f", arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					void BenchmarkT<T>::RunWithArg(T arg) {
 | 
				
			||||||
 | 
					  int new_iterations = 1;
 | 
				
			||||||
 | 
					  int iterations;
 | 
				
			||||||
 | 
					  while (new_iterations < 1e8) {
 | 
				
			||||||
 | 
					    bytes_processed_ = 0;
 | 
				
			||||||
 | 
					    total_time_ns_ = 0;
 | 
				
			||||||
 | 
					    start_time_ns_ = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iterations = new_iterations;
 | 
				
			||||||
 | 
					    RunIterations(iterations, arg);
 | 
				
			||||||
 | 
					    if (total_time_ns_ >= 1e9) {
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (total_time_ns_/iterations == 0) {
 | 
				
			||||||
 | 
					      new_iterations = 1e9;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      new_iterations = 1e9/ (total_time_ns_/iterations);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    new_iterations = std::max(iterations + 1,
 | 
				
			||||||
 | 
					                          std::min(new_iterations + new_iterations/2, 100*iterations));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    new_iterations = Round(new_iterations);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf("%-*s %10s %10" PRId64, MaxNameColumnWidth(), GetNameStr(arg).c_str(),
 | 
				
			||||||
 | 
					         PrettyInt(iterations, 10).c_str(), total_time_ns_/iterations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (total_time_ns_ > 0 && bytes_processed_ > 0) {
 | 
				
			||||||
 | 
					    double gib_processed = static_cast<double>(bytes_processed_)/1e9;
 | 
				
			||||||
 | 
					    double seconds = static_cast<double>(total_time_ns_)/1e9;
 | 
				
			||||||
 | 
					    printf(" %8.3f GiB/s", gib_processed/seconds);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  printf("\n");
 | 
				
			||||||
 | 
					  fflush(stdout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template class BenchmarkT<int>;
 | 
				
			||||||
 | 
					template class BenchmarkT<double>;
 | 
				
			||||||
 | 
					template class BenchmarkT<void*>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template class BenchmarkWithArg<int>;
 | 
				
			||||||
 | 
					template class BenchmarkWithArg<double>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace testing
 | 
				
			||||||
							
								
								
									
										154
									
								
								benchmarks/benchmark/Benchmark.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								benchmarks/benchmark/Benchmark.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2012 The Android Open Source Project
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef BENCHMARKS_BENCHMARK_H_
 | 
				
			||||||
 | 
					#define BENCHMARKS_BENCHMARK_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <regex.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace testing {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Benchmark {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  Benchmark() {
 | 
				
			||||||
 | 
					    List().push_back(this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  virtual ~Benchmark() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual std::string Name() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void RunAll() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool ShouldRun(std::vector<regex_t*>&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void SetBenchmarkBytesProcessed(uint64_t bytes) { bytes_processed_ += bytes; }
 | 
				
			||||||
 | 
					  void StopBenchmarkTiming();
 | 
				
			||||||
 | 
					  void StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Run all of the benchmarks that have registered.
 | 
				
			||||||
 | 
					  static bool RunAll(std::vector<regex_t*>&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static std::vector<Benchmark*>& List();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static size_t MaxNameColumnWidth();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual size_t NameColumnWidth() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint64_t bytes_processed_;
 | 
				
			||||||
 | 
					  uint64_t total_time_ns_;
 | 
				
			||||||
 | 
					  uint64_t start_time_ns_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					class BenchmarkT : public Benchmark {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  BenchmarkT() {}
 | 
				
			||||||
 | 
					  virtual ~BenchmarkT() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  void RunWithArg(T arg);
 | 
				
			||||||
 | 
					  virtual void RunIterations(int, T) = 0;
 | 
				
			||||||
 | 
					  virtual std::string GetNameStr(T) = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BenchmarkWithoutArg : public BenchmarkT<void*> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  BenchmarkWithoutArg() {}
 | 
				
			||||||
 | 
					  virtual ~BenchmarkWithoutArg() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual void RunAll() override {
 | 
				
			||||||
 | 
					    RunWithArg(nullptr);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void RunIterations(int iters, void*) override {
 | 
				
			||||||
 | 
					    Run(iters);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void Run(int) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual size_t NameColumnWidth() override {
 | 
				
			||||||
 | 
					    return Name().size();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual std::string GetNameStr(void *) override;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					class BenchmarkWithArg : public BenchmarkT<T> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  BenchmarkWithArg() {}
 | 
				
			||||||
 | 
					  virtual ~BenchmarkWithArg() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BenchmarkWithArg* Arg(T arg) {
 | 
				
			||||||
 | 
					    args_.push_back(arg);
 | 
				
			||||||
 | 
					    return this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual size_t NameColumnWidth() override {
 | 
				
			||||||
 | 
					    size_t max = 0;
 | 
				
			||||||
 | 
					    for (const auto arg : args_) {
 | 
				
			||||||
 | 
					      max = std::max(max, GetNameStr(arg).size());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return max;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::string GetNameStr(T arg) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void RunAll() override {
 | 
				
			||||||
 | 
					    for (T arg : args_) {
 | 
				
			||||||
 | 
					      BenchmarkT<T>::RunWithArg(arg);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void RunIterations(int iters, T arg) override {
 | 
				
			||||||
 | 
					    Run(iters, arg);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void Run(int iters, T arg) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  std::vector<T> args_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BENCHMARK_START(f, super_class) \
 | 
				
			||||||
 | 
					  class f : public super_class { \
 | 
				
			||||||
 | 
					  public: \
 | 
				
			||||||
 | 
					    f() {} \
 | 
				
			||||||
 | 
					    virtual ~f() {} \
 | 
				
			||||||
 | 
					    virtual std::string Name() override { return #f; } \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BENCHMARK_NO_ARG(f) \
 | 
				
			||||||
 | 
					  BENCHMARK_START(f, ::testing::BenchmarkWithoutArg) \
 | 
				
			||||||
 | 
					    virtual void Run(int) override; \
 | 
				
			||||||
 | 
					  }; \
 | 
				
			||||||
 | 
					  static ::testing::Benchmark* __benchmark_##f = new f()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BENCHMARK_WITH_ARG(f, arg_type) \
 | 
				
			||||||
 | 
					  BENCHMARK_START(f, ::testing::BenchmarkWithArg<arg_type>) \
 | 
				
			||||||
 | 
					    virtual void Run(int, arg_type) override; \
 | 
				
			||||||
 | 
					  }; \
 | 
				
			||||||
 | 
					  static ::testing::BenchmarkWithArg<arg_type>* __benchmark_##f = (new f())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // BENCHMARKS_BENCHMARK_H_
 | 
				
			||||||
@@ -1,266 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (C) 2012 The Android Open Source Project
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * 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
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *      http://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 <benchmark.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <regex.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <inttypes.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int64_t g_bytes_processed;
 | 
					 | 
				
			||||||
static int64_t g_benchmark_total_time_ns;
 | 
					 | 
				
			||||||
static int64_t g_benchmark_start_time_ns;
 | 
					 | 
				
			||||||
static int g_name_column_width = 20;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef std::vector<::testing::Benchmark*> BenchmarkList;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static BenchmarkList& Benchmarks() {
 | 
					 | 
				
			||||||
  static BenchmarkList benchmarks;
 | 
					 | 
				
			||||||
  return benchmarks;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Similar to the code in art, but supporting both binary and decimal prefixes.
 | 
					 | 
				
			||||||
static std::string PrettyInt(uint64_t count, size_t base) {
 | 
					 | 
				
			||||||
  if (base != 2 && base != 10) abort();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // The byte thresholds at which we display amounts. A count is displayed
 | 
					 | 
				
			||||||
  // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
 | 
					 | 
				
			||||||
  static const uint64_t kUnitThresholds2[] = {
 | 
					 | 
				
			||||||
    1024*1024*1024 /* Gi */, 2*1024*1024 /* Mi */, 3*1024 /* Ki */, 0,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  static const uint64_t kUnitThresholds10[] = {
 | 
					 | 
				
			||||||
    1000*1000*1000 /* G */, 2*1000*1000 /* M */, 3*1000 /* k */, 0,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  static const uint64_t kAmountPerUnit2[] = { 1024*1024*1024, 1024*1024, 1024, 1 };
 | 
					 | 
				
			||||||
  static const uint64_t kAmountPerUnit10[] = { 1000*1000*1000, 1000*1000, 1000, 1 };
 | 
					 | 
				
			||||||
  static const char* const kUnitStrings2[] = { "Gi", "Mi", "Ki", "" };
 | 
					 | 
				
			||||||
  static const char* const kUnitStrings10[] = { "G", "M", "k", "" };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Which set are we using?
 | 
					 | 
				
			||||||
  const uint64_t* kUnitThresholds = ((base == 2) ? kUnitThresholds2 : kUnitThresholds10);
 | 
					 | 
				
			||||||
  const uint64_t* kAmountPerUnit = ((base == 2) ? kAmountPerUnit2 : kAmountPerUnit10);
 | 
					 | 
				
			||||||
  const char* const* kUnitStrings = ((base == 2) ? kUnitStrings2 : kUnitStrings10);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  size_t i = 0;
 | 
					 | 
				
			||||||
  for (; kUnitThresholds[i] != 0; ++i) {
 | 
					 | 
				
			||||||
    if (count >= kUnitThresholds[i]) {
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  char* s = NULL;
 | 
					 | 
				
			||||||
  asprintf(&s, "%" PRId64 "%s", count / kAmountPerUnit[i], kUnitStrings[i]);
 | 
					 | 
				
			||||||
  std::string result(s);
 | 
					 | 
				
			||||||
  free(s);
 | 
					 | 
				
			||||||
  return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int Round(int n) {
 | 
					 | 
				
			||||||
  int base = 1;
 | 
					 | 
				
			||||||
  while (base*10 < n) {
 | 
					 | 
				
			||||||
    base *= 10;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (n < 2*base) {
 | 
					 | 
				
			||||||
    return 2*base;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (n < 5*base) {
 | 
					 | 
				
			||||||
    return 5*base;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return 10*base;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int64_t NanoTime() {
 | 
					 | 
				
			||||||
  struct timespec t;
 | 
					 | 
				
			||||||
  t.tv_sec = t.tv_nsec = 0;
 | 
					 | 
				
			||||||
  clock_gettime(CLOCK_MONOTONIC, &t);
 | 
					 | 
				
			||||||
  return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace testing {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Benchmark* Benchmark::Arg(int arg) {
 | 
					 | 
				
			||||||
  args_.push_back(arg);
 | 
					 | 
				
			||||||
  return this;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const char* Benchmark::Name() {
 | 
					 | 
				
			||||||
  return name_;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool Benchmark::ShouldRun(int argc, char* argv[]) {
 | 
					 | 
				
			||||||
  if (argc == 1) {
 | 
					 | 
				
			||||||
    return true;  // With no arguments, we run all benchmarks.
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  // Otherwise, we interpret each argument as a regular expression and
 | 
					 | 
				
			||||||
  // see if any of our benchmarks match.
 | 
					 | 
				
			||||||
  for (int i = 1; i < argc; i++) {
 | 
					 | 
				
			||||||
    regex_t re;
 | 
					 | 
				
			||||||
    if (regcomp(&re, argv[i], 0) != 0) {
 | 
					 | 
				
			||||||
      fprintf(stderr, "couldn't compile \"%s\" as a regular expression!\n", argv[i]);
 | 
					 | 
				
			||||||
      exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    int match = regexec(&re, name_, 0, NULL, 0);
 | 
					 | 
				
			||||||
    regfree(&re);
 | 
					 | 
				
			||||||
    if (match != REG_NOMATCH) {
 | 
					 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Benchmark::Register(const char* name, void (*fn)(int), void (*fn_range)(int, int)) {
 | 
					 | 
				
			||||||
  name_ = name;
 | 
					 | 
				
			||||||
  fn_ = fn;
 | 
					 | 
				
			||||||
  fn_range_ = fn_range;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (fn_ == NULL && fn_range_ == NULL) {
 | 
					 | 
				
			||||||
    fprintf(stderr, "%s: missing function\n", name_);
 | 
					 | 
				
			||||||
    exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Benchmarks().push_back(this);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Benchmark::Run() {
 | 
					 | 
				
			||||||
  if (fn_ != NULL) {
 | 
					 | 
				
			||||||
    RunWithArg(0);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    if (args_.empty()) {
 | 
					 | 
				
			||||||
      fprintf(stderr, "%s: no args!\n", name_);
 | 
					 | 
				
			||||||
      exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for (size_t i = 0; i < args_.size(); ++i) {
 | 
					 | 
				
			||||||
      RunWithArg(args_[i]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Benchmark::RunRepeatedlyWithArg(int iterations, int arg) {
 | 
					 | 
				
			||||||
  g_bytes_processed = 0;
 | 
					 | 
				
			||||||
  g_benchmark_total_time_ns = 0;
 | 
					 | 
				
			||||||
  g_benchmark_start_time_ns = NanoTime();
 | 
					 | 
				
			||||||
  if (fn_ != NULL) {
 | 
					 | 
				
			||||||
    fn_(iterations);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    fn_range_(iterations, arg);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (g_benchmark_start_time_ns != 0) {
 | 
					 | 
				
			||||||
    g_benchmark_total_time_ns += NanoTime() - g_benchmark_start_time_ns;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Benchmark::RunWithArg(int arg) {
 | 
					 | 
				
			||||||
  // Run once in case it's expensive.
 | 
					 | 
				
			||||||
  int iterations = 1;
 | 
					 | 
				
			||||||
  int64_t realStartTime = NanoTime();
 | 
					 | 
				
			||||||
  RunRepeatedlyWithArg(iterations, arg);
 | 
					 | 
				
			||||||
  int64_t realTotalTime = NanoTime() - realStartTime;
 | 
					 | 
				
			||||||
  while (realTotalTime < 1e9 && iterations < 1e8) {
 | 
					 | 
				
			||||||
    int last = iterations;
 | 
					 | 
				
			||||||
    if (realTotalTime/iterations == 0) {
 | 
					 | 
				
			||||||
      iterations = 1e9;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      iterations = 1e9 / (realTotalTime/iterations);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    iterations = std::max(last + 1, std::min(iterations + iterations/2, 100*last));
 | 
					 | 
				
			||||||
    iterations = Round(iterations);
 | 
					 | 
				
			||||||
    realStartTime = NanoTime();
 | 
					 | 
				
			||||||
    RunRepeatedlyWithArg(iterations, arg);
 | 
					 | 
				
			||||||
    realTotalTime = NanoTime() - realStartTime;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  char throughput[100];
 | 
					 | 
				
			||||||
  throughput[0] = '\0';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (g_benchmark_total_time_ns > 0 && g_bytes_processed > 0) {
 | 
					 | 
				
			||||||
    double gib_processed = static_cast<double>(g_bytes_processed)/1e9;
 | 
					 | 
				
			||||||
    double seconds = static_cast<double>(g_benchmark_total_time_ns)/1e9;
 | 
					 | 
				
			||||||
    snprintf(throughput, sizeof(throughput), " %8.3f GiB/s", gib_processed/seconds);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  char full_name[100];
 | 
					 | 
				
			||||||
  if (fn_range_ != NULL) {
 | 
					 | 
				
			||||||
    snprintf(full_name, sizeof(full_name), "%s/%s", name_, PrettyInt(arg, 2).c_str());
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    snprintf(full_name, sizeof(full_name), "%s", name_);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  printf("%-*s %10s %10" PRId64 "%s\n",
 | 
					 | 
				
			||||||
         g_name_column_width, full_name,
 | 
					 | 
				
			||||||
         PrettyInt(iterations, 10).c_str(),
 | 
					 | 
				
			||||||
         g_benchmark_total_time_ns/iterations,
 | 
					 | 
				
			||||||
         throughput);
 | 
					 | 
				
			||||||
  fflush(stdout);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace testing
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void SetBenchmarkBytesProcessed(int64_t x) {
 | 
					 | 
				
			||||||
  g_bytes_processed = x;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void StopBenchmarkTiming() {
 | 
					 | 
				
			||||||
  if (g_benchmark_start_time_ns != 0) {
 | 
					 | 
				
			||||||
    g_benchmark_total_time_ns += NanoTime() - g_benchmark_start_time_ns;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  g_benchmark_start_time_ns = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void StartBenchmarkTiming() {
 | 
					 | 
				
			||||||
  if (g_benchmark_start_time_ns == 0) {
 | 
					 | 
				
			||||||
    g_benchmark_start_time_ns = NanoTime();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char* argv[]) {
 | 
					 | 
				
			||||||
  if (Benchmarks().empty()) {
 | 
					 | 
				
			||||||
    fprintf(stderr, "No benchmarks registered!\n");
 | 
					 | 
				
			||||||
    exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (auto& b : Benchmarks()) {
 | 
					 | 
				
			||||||
    int name_width = static_cast<int>(strlen(b->Name()));
 | 
					 | 
				
			||||||
    g_name_column_width = std::max(g_name_column_width, name_width);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool need_header = true;
 | 
					 | 
				
			||||||
  for (auto& b : Benchmarks()) {
 | 
					 | 
				
			||||||
    if (b->ShouldRun(argc, argv)) {
 | 
					 | 
				
			||||||
      if (need_header) {
 | 
					 | 
				
			||||||
        printf("%-*s %10s %10s\n", g_name_column_width, "", "iterations", "ns/op");
 | 
					 | 
				
			||||||
        fflush(stdout);
 | 
					 | 
				
			||||||
        need_header = false;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      b->Run();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (need_header) {
 | 
					 | 
				
			||||||
    fprintf(stderr, "No matching benchmarks!\n");
 | 
					 | 
				
			||||||
    fprintf(stderr, "Available benchmarks:\n");
 | 
					 | 
				
			||||||
    for (auto& b : Benchmarks()) {
 | 
					 | 
				
			||||||
      fprintf(stderr, "  %s\n", b->Name());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,65 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (C) 2012 The Android Open Source Project
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * 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
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *      http://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.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef BENCHMARKS_BENCHMARK_H_
 | 
					 | 
				
			||||||
#define BENCHMARKS_BENCHMARK_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace testing {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Benchmark {
 | 
					 | 
				
			||||||
 public:
 | 
					 | 
				
			||||||
  Benchmark(const char* name, void (*fn)(int)) {
 | 
					 | 
				
			||||||
    Register(name, fn, NULL);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Benchmark(const char* name, void (*fn_range)(int, int)) {
 | 
					 | 
				
			||||||
    Register(name, NULL, fn_range);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Benchmark* Arg(int x);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const char* Name();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool ShouldRun(int argc, char* argv[]);
 | 
					 | 
				
			||||||
  void Run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 private:
 | 
					 | 
				
			||||||
  const char* name_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void (*fn_)(int);
 | 
					 | 
				
			||||||
  void (*fn_range_)(int, int);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  std::vector<int> args_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void Register(const char* name, void (*fn)(int), void (*fn_range)(int, int));
 | 
					 | 
				
			||||||
  void RunRepeatedlyWithArg(int iterations, int arg);
 | 
					 | 
				
			||||||
  void RunWithArg(int arg);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace testing
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void SetBenchmarkBytesProcessed(int64_t);
 | 
					 | 
				
			||||||
void StopBenchmarkTiming();
 | 
					 | 
				
			||||||
void StartBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BENCHMARK(f) \
 | 
					 | 
				
			||||||
    static ::testing::Benchmark* _benchmark_##f __attribute__((unused)) = \
 | 
					 | 
				
			||||||
        (new ::testing::Benchmark(#f, f))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
							
								
								
									
										61
									
								
								benchmarks/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								benchmarks/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2012 The Android Open Source Project
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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 <regex.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char* argv[]) {
 | 
				
			||||||
 | 
					  if (::testing::Benchmark::List().empty()) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "No benchmarks registered!\n");
 | 
				
			||||||
 | 
					    exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<regex_t*> regs;
 | 
				
			||||||
 | 
					  for (int i = 1; i < argc; i++) {
 | 
				
			||||||
 | 
					    regex_t* re = new regex_t;
 | 
				
			||||||
 | 
					    int errcode = regcomp(re, argv[i], 0);
 | 
				
			||||||
 | 
					    if (errcode != 0) {
 | 
				
			||||||
 | 
					      size_t errbuf_size = regerror(errcode, re, NULL, 0);
 | 
				
			||||||
 | 
					      if (errbuf_size > 0) {
 | 
				
			||||||
 | 
					        char* errbuf = new char[errbuf_size];
 | 
				
			||||||
 | 
					        regerror(errcode, re, errbuf, errbuf_size);
 | 
				
			||||||
 | 
					        fprintf(stderr, "Couldn't compile \"%s\" as a regular expression: %s\n",
 | 
				
			||||||
 | 
					                argv[i], errbuf);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        fprintf(stderr, "Unknown compile error for \"%s\" as a regular expression!\n", argv[i]);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    regs.push_back(re);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!::testing::Benchmark::RunAll(regs)) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "No matching benchmarks!\n");
 | 
				
			||||||
 | 
					    fprintf(stderr, "Available benchmarks:\n");
 | 
				
			||||||
 | 
					    for (const auto& benchmark : ::testing::Benchmark::List()) {
 | 
				
			||||||
 | 
					      fprintf(stderr, "  %s\n", benchmark->Name().c_str());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,16 +14,20 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <fenv.h>
 | 
					#include <fenv.h>
 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AT_COMMON_VALS \
 | 
				
			||||||
 | 
					    Arg(1234.0)->Arg(nan(""))->Arg(HUGE_VAL)->Arg(0.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Avoid optimization.
 | 
					// Avoid optimization.
 | 
				
			||||||
volatile double d;
 | 
					volatile double d;
 | 
				
			||||||
volatile double v;
 | 
					volatile double v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_math_sqrt(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_math_sqrt);
 | 
				
			||||||
 | 
					void BM_math_sqrt::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  d = 0.0;
 | 
					  d = 0.0;
 | 
				
			||||||
@@ -34,9 +38,9 @@ static void BM_math_sqrt(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_math_sqrt);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_math_log10(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_math_log10);
 | 
				
			||||||
 | 
					void BM_math_log10::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  d = 0.0;
 | 
					  d = 0.0;
 | 
				
			||||||
@@ -47,9 +51,9 @@ static void BM_math_log10(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_math_log10);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_math_logb(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_math_logb);
 | 
				
			||||||
 | 
					void BM_math_logb::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  d = 0.0;
 | 
					  d = 0.0;
 | 
				
			||||||
@@ -60,61 +64,22 @@ static void BM_math_logb(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_math_logb);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_math_isinf_NORMAL(int iters) {
 | 
					BENCHMARK_WITH_ARG(BM_math_isinf, double)->AT_COMMON_VALS;
 | 
				
			||||||
 | 
					void BM_math_isinf::Run(int iters, double value) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  d = 0.0;
 | 
					  d = 0.0;
 | 
				
			||||||
  v = 1234.0; // FP_NORMAL
 | 
					  v = value;
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
    d += (isinf)(v);
 | 
					    d += (isinf)(v);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_math_isinf_NORMAL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_math_isinf_NAN(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_math_sin_fast);
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					void BM_math_sin_fast::Run(int iters) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  d = 0.0;
 | 
					 | 
				
			||||||
  v = nan(""); // FP_NAN
 | 
					 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					 | 
				
			||||||
    d += (isinf)(v);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_math_isinf_NAN);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_math_isinf_INFINITE(int iters) {
 | 
					 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  d = 0.0;
 | 
					 | 
				
			||||||
  v = HUGE_VAL; // FP_INFINITE
 | 
					 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					 | 
				
			||||||
    d += (isinf)(v);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_math_isinf_INFINITE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_math_isinf_ZERO(int iters) {
 | 
					 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  d = 0.0;
 | 
					 | 
				
			||||||
  v = 0.0; // FP_ZERO
 | 
					 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					 | 
				
			||||||
    d += (isinf)(v);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_math_isinf_ZERO);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_math_sin_fast(int iters) {
 | 
					 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  d = 1.0;
 | 
					  d = 1.0;
 | 
				
			||||||
@@ -124,9 +89,9 @@ static void BM_math_sin_fast(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_math_sin_fast);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_math_sin_feupdateenv(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_math_sin_feupdateenv);
 | 
				
			||||||
 | 
					void BM_math_sin_feupdateenv::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  d = 1.0;
 | 
					  d = 1.0;
 | 
				
			||||||
@@ -140,9 +105,9 @@ static void BM_math_sin_feupdateenv(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_math_sin_feupdateenv);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_math_sin_fesetenv(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_math_sin_fesetenv);
 | 
				
			||||||
 | 
					void BM_math_sin_fesetenv::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  d = 1.0;
 | 
					  d = 1.0;
 | 
				
			||||||
@@ -156,56 +121,16 @@ static void BM_math_sin_fesetenv(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_math_sin_fesetenv);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_math_fpclassify_NORMAL(int iters) {
 | 
					BENCHMARK_WITH_ARG(BM_math_fpclassify, double)->AT_COMMON_VALS;
 | 
				
			||||||
 | 
					void BM_math_fpclassify::Run(int iters, double value) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  d = 0.0;
 | 
					  d = 0.0;
 | 
				
			||||||
  v = 1234.0; // FP_NORMAL
 | 
					  v = value;
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
    d += fpclassify(v);
 | 
					    d += fpclassify(v);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_math_fpclassify_NORMAL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_math_fpclassify_NAN(int iters) {
 | 
					 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  d = 0.0;
 | 
					 | 
				
			||||||
  v = nan(""); // FP_NAN
 | 
					 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					 | 
				
			||||||
    d += fpclassify(v);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_math_fpclassify_NAN);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_math_fpclassify_INFINITE(int iters) {
 | 
					 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  d = 0.0;
 | 
					 | 
				
			||||||
  v = HUGE_VAL; // FP_INFINITE
 | 
					 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					 | 
				
			||||||
    d += fpclassify(v);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_math_fpclassify_INFINITE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_math_fpclassify_ZERO(int iters) {
 | 
					 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  d = 0.0;
 | 
					 | 
				
			||||||
  v = 0.0; // FP_ZERO
 | 
					 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					 | 
				
			||||||
    d += fpclassify(v);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_math_fpclassify_ZERO);
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,19 +14,21 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark.h"
 | 
					 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__BIONIC__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 | 
					#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 | 
				
			||||||
#include <sys/_system_properties.h>
 | 
					#include <sys/_system_properties.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <vector>
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void *__system_property_area__;
 | 
					extern void* __system_property_area__;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Do not exceed 512, that is about the largest number of properties
 | 
					// Do not exceed 512, that is about the largest number of properties
 | 
				
			||||||
// that can be created with the current property area size.
 | 
					// that can be created with the current property area size.
 | 
				
			||||||
@@ -44,7 +46,7 @@ struct LocalPropertyTestState {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    char dir_template[PATH_MAX];
 | 
					    char dir_template[PATH_MAX];
 | 
				
			||||||
    snprintf(dir_template, sizeof(dir_template), "%s/local/tmp/prop-XXXXXX", android_data);
 | 
					    snprintf(dir_template, sizeof(dir_template), "%s/local/tmp/prop-XXXXXX", android_data);
 | 
				
			||||||
        char *dirname = mkdtemp(dir_template);
 | 
					    char* dirname = mkdtemp(dir_template);
 | 
				
			||||||
    if (!dirname) {
 | 
					    if (!dirname) {
 | 
				
			||||||
      printf("making temp file for test state failed (is %s/local/tmp writable?): %s\n",
 | 
					      printf("making temp file for test state failed (is %s/local/tmp writable?): %s\n",
 | 
				
			||||||
             android_data, strerror(errno));
 | 
					             android_data, strerror(errno));
 | 
				
			||||||
@@ -126,20 +128,20 @@ struct LocalPropertyTestState {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  const int nprops;
 | 
					  const int nprops;
 | 
				
			||||||
    char **names;
 | 
					  char** names;
 | 
				
			||||||
    int *name_lens;
 | 
					  int* name_lens;
 | 
				
			||||||
    char **values;
 | 
					  char** values;
 | 
				
			||||||
    int *value_lens;
 | 
					  int* value_lens;
 | 
				
			||||||
  bool valid;
 | 
					  bool valid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  std::string pa_dirname;
 | 
					  std::string pa_dirname;
 | 
				
			||||||
  std::string pa_filename;
 | 
					  std::string pa_filename;
 | 
				
			||||||
    void *old_pa;
 | 
					  void* old_pa;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_property_get(int iters, int nprops)
 | 
					BENCHMARK_WITH_ARG(BM_property_get, int)->TEST_NUM_PROPS;
 | 
				
			||||||
{
 | 
					void BM_property_get::Run(int iters, int nprops) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LocalPropertyTestState pa(nprops);
 | 
					  LocalPropertyTestState pa(nprops);
 | 
				
			||||||
@@ -157,10 +159,9 @@ static void BM_property_get(int iters, int nprops)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_property_get)->TEST_NUM_PROPS;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_property_find(int iters, int nprops)
 | 
					BENCHMARK_WITH_ARG(BM_property_find, int)->TEST_NUM_PROPS;
 | 
				
			||||||
{
 | 
					void BM_property_find::Run(int iters, int nprops) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LocalPropertyTestState pa(nprops);
 | 
					  LocalPropertyTestState pa(nprops);
 | 
				
			||||||
@@ -177,10 +178,9 @@ static void BM_property_find(int iters, int nprops)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_property_find)->TEST_NUM_PROPS;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_property_read(int iters, int nprops)
 | 
					BENCHMARK_WITH_ARG(BM_property_read, int)->TEST_NUM_PROPS;
 | 
				
			||||||
{
 | 
					void BM_property_read::Run(int iters, int nprops) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LocalPropertyTestState pa(nprops);
 | 
					  LocalPropertyTestState pa(nprops);
 | 
				
			||||||
@@ -204,10 +204,9 @@ static void BM_property_read(int iters, int nprops)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  delete[] pinfo;
 | 
					  delete[] pinfo;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_property_read)->TEST_NUM_PROPS;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_property_serial(int iters, int nprops)
 | 
					BENCHMARK_WITH_ARG(BM_property_serial, int)->TEST_NUM_PROPS;
 | 
				
			||||||
{
 | 
					void BM_property_serial::Run(int iters, int nprops) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LocalPropertyTestState pa(nprops);
 | 
					  LocalPropertyTestState pa(nprops);
 | 
				
			||||||
@@ -230,4 +229,5 @@ static void BM_property_serial(int iters, int nprops)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  delete[] pinfo;
 | 
					  delete[] pinfo;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_property_serial)->TEST_NUM_PROPS;
 | 
					
 | 
				
			||||||
 | 
					#endif  // __BIONIC__
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,14 +14,15 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <pthread.h>
 | 
					#include <pthread.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Stop GCC optimizing out our pure function.
 | 
					// Stop GCC optimizing out our pure function.
 | 
				
			||||||
/* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;
 | 
					/* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_self(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_self);
 | 
				
			||||||
 | 
					void BM_pthread_self::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
@@ -30,9 +31,9 @@ static void BM_pthread_self(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_self);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_getspecific(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_getspecific);
 | 
				
			||||||
 | 
					void BM_pthread_getspecific::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_key_t key;
 | 
					  pthread_key_t key;
 | 
				
			||||||
  pthread_key_create(&key, NULL);
 | 
					  pthread_key_create(&key, NULL);
 | 
				
			||||||
@@ -45,9 +46,9 @@ static void BM_pthread_getspecific(int iters) {
 | 
				
			|||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_key_delete(key);
 | 
					  pthread_key_delete(key);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_getspecific);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_setspecific(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_setspecific);
 | 
				
			||||||
 | 
					void BM_pthread_setspecific::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_key_t key;
 | 
					  pthread_key_t key;
 | 
				
			||||||
  pthread_key_create(&key, NULL);
 | 
					  pthread_key_create(&key, NULL);
 | 
				
			||||||
@@ -60,12 +61,12 @@ static void BM_pthread_setspecific(int iters) {
 | 
				
			|||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_key_delete(key);
 | 
					  pthread_key_delete(key);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_setspecific);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void DummyPthreadOnceInitFunction() {
 | 
					static void DummyPthreadOnceInitFunction() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_once(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_once);
 | 
				
			||||||
 | 
					void BM_pthread_once::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_once_t once = PTHREAD_ONCE_INIT;
 | 
					  pthread_once_t once = PTHREAD_ONCE_INIT;
 | 
				
			||||||
  pthread_once(&once, DummyPthreadOnceInitFunction);
 | 
					  pthread_once(&once, DummyPthreadOnceInitFunction);
 | 
				
			||||||
@@ -77,9 +78,9 @@ static void BM_pthread_once(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_once);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_mutex_lock(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_mutex_lock);
 | 
				
			||||||
 | 
					void BM_pthread_mutex_lock::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 | 
					  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
@@ -91,9 +92,9 @@ static void BM_pthread_mutex_lock(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_mutex_lock);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_mutex_lock_ERRORCHECK(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_mutex_lock_ERRORCHECK);
 | 
				
			||||||
 | 
					void BM_pthread_mutex_lock_ERRORCHECK::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
 | 
					  pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
@@ -105,9 +106,9 @@ static void BM_pthread_mutex_lock_ERRORCHECK(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_mutex_lock_RECURSIVE);
 | 
				
			||||||
 | 
					void BM_pthread_mutex_lock_RECURSIVE::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 | 
					  pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
@@ -119,9 +120,9 @@ static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_rw_lock_read(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_rw_lock_read);
 | 
				
			||||||
 | 
					void BM_pthread_rw_lock_read::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_rwlock_t lock;
 | 
					  pthread_rwlock_t lock;
 | 
				
			||||||
  pthread_rwlock_init(&lock, NULL);
 | 
					  pthread_rwlock_init(&lock, NULL);
 | 
				
			||||||
@@ -135,9 +136,9 @@ static void BM_pthread_rw_lock_read(int iters) {
 | 
				
			|||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_rwlock_destroy(&lock);
 | 
					  pthread_rwlock_destroy(&lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_rw_lock_read);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_rw_lock_write(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_rw_lock_write);
 | 
				
			||||||
 | 
					void BM_pthread_rw_lock_write::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_rwlock_t lock;
 | 
					  pthread_rwlock_t lock;
 | 
				
			||||||
  pthread_rwlock_init(&lock, NULL);
 | 
					  pthread_rwlock_init(&lock, NULL);
 | 
				
			||||||
@@ -151,13 +152,13 @@ static void BM_pthread_rw_lock_write(int iters) {
 | 
				
			|||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_rwlock_destroy(&lock);
 | 
					  pthread_rwlock_destroy(&lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_rw_lock_write);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* IdleThread(void*) {
 | 
					static void* IdleThread(void*) {
 | 
				
			||||||
  return NULL;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_create(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_create);
 | 
				
			||||||
 | 
					void BM_pthread_create::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_t thread;
 | 
					  pthread_t thread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -168,43 +169,45 @@ static void BM_pthread_create(int iters) {
 | 
				
			|||||||
    pthread_join(thread, NULL);
 | 
					    pthread_join(thread, NULL);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_create);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* RunThread(void*) {
 | 
					static void* RunThread(void* arg) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  ::testing::Benchmark* benchmark = reinterpret_cast<::testing::Benchmark*>(arg);
 | 
				
			||||||
 | 
					  benchmark->StopBenchmarkTiming();
 | 
				
			||||||
  return NULL;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_create_and_run(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_create_and_run);
 | 
				
			||||||
 | 
					void BM_pthread_create_and_run::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_t thread;
 | 
					  pthread_t thread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
    StartBenchmarkTiming();
 | 
					    StartBenchmarkTiming();
 | 
				
			||||||
    pthread_create(&thread, NULL, RunThread, NULL);
 | 
					    pthread_create(&thread, NULL, RunThread, this);
 | 
				
			||||||
    pthread_join(thread, NULL);
 | 
					    pthread_join(thread, NULL);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_create_and_run);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* ExitThread(void*) {
 | 
					static void* ExitThread(void* arg) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  ::testing::Benchmark* benchmark = reinterpret_cast<::testing::Benchmark*>(arg);
 | 
				
			||||||
 | 
					  benchmark->StartBenchmarkTiming();
 | 
				
			||||||
  pthread_exit(NULL);
 | 
					  pthread_exit(NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_exit_and_join(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_exit_and_join);
 | 
				
			||||||
 | 
					void BM_pthread_exit_and_join::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_t thread;
 | 
					  pthread_t thread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
    pthread_create(&thread, NULL, ExitThread, NULL);
 | 
					    pthread_create(&thread, NULL, ExitThread, this);
 | 
				
			||||||
    pthread_join(thread, NULL);
 | 
					    pthread_join(thread, NULL);
 | 
				
			||||||
    StopBenchmarkTiming();
 | 
					    StopBenchmarkTiming();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_exit_and_join);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_key_create(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_key_create);
 | 
				
			||||||
 | 
					void BM_pthread_key_create::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_key_t key;
 | 
					  pthread_key_t key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -215,9 +218,9 @@ static void BM_pthread_key_create(int iters) {
 | 
				
			|||||||
    pthread_key_delete(key);
 | 
					    pthread_key_delete(key);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_key_create);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_pthread_key_delete(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_pthread_key_delete);
 | 
				
			||||||
 | 
					void BM_pthread_key_delete::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  pthread_key_t key;
 | 
					  pthread_key_t key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -228,4 +231,3 @@ static void BM_pthread_key_delete(int iters) {
 | 
				
			|||||||
    StopBenchmarkTiming();
 | 
					    StopBenchmarkTiming();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_pthread_key_delete);
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,14 +14,15 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <pthread.h>
 | 
					#include <pthread.h>
 | 
				
			||||||
#include <semaphore.h>
 | 
					#include <semaphore.h>
 | 
				
			||||||
#include <stdatomic.h>
 | 
					#include <stdatomic.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_semaphore_sem_getvalue(int iters) {
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BENCHMARK_NO_ARG(BM_semaphore_sem_getvalue);
 | 
				
			||||||
 | 
					void BM_semaphore_sem_getvalue::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  sem_t semaphore;
 | 
					  sem_t semaphore;
 | 
				
			||||||
  sem_init(&semaphore, 1, 1);
 | 
					  sem_init(&semaphore, 1, 1);
 | 
				
			||||||
@@ -34,9 +35,9 @@ static void BM_semaphore_sem_getvalue(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_semaphore_sem_getvalue);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_semaphore_sem_wait_sem_post(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_semaphore_sem_wait_sem_post);
 | 
				
			||||||
 | 
					void BM_semaphore_sem_wait_sem_post::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  sem_t semaphore;
 | 
					  sem_t semaphore;
 | 
				
			||||||
  sem_init(&semaphore, 1, 1);
 | 
					  sem_init(&semaphore, 1, 1);
 | 
				
			||||||
@@ -49,7 +50,6 @@ static void BM_semaphore_sem_wait_sem_post(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_semaphore_sem_wait_sem_post);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 *    This test reports the overhead of the underlying futex wake syscall on
 | 
					 *    This test reports the overhead of the underlying futex wake syscall on
 | 
				
			||||||
@@ -87,7 +87,8 @@ static void *BM_semaphore_sem_post_start_thread(void *obj) {
 | 
				
			|||||||
    return NULL;
 | 
					    return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_semaphore_sem_post(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_semaphore_sem_post);
 | 
				
			||||||
 | 
					void BM_semaphore_sem_post::Run(int iters) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sem_t semaphore;
 | 
					  sem_t semaphore;
 | 
				
			||||||
@@ -100,9 +101,6 @@ static void BM_semaphore_sem_post(int iters) {
 | 
				
			|||||||
  pthread_attr_setschedparam(&attr, ¶m);
 | 
					  pthread_attr_setschedparam(&attr, ¶m);
 | 
				
			||||||
  pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
 | 
					  pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
 | 
				
			||||||
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 | 
					  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 | 
				
			||||||
#ifdef PTHREAD_SET_INHERIT_SCHED
 | 
					 | 
				
			||||||
  pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  pthread_t pthread;
 | 
					  pthread_t pthread;
 | 
				
			||||||
  pthread_create(&pthread, &attr, BM_semaphore_sem_post_start_thread, &semaphore);
 | 
					  pthread_create(&pthread, &attr, BM_semaphore_sem_post_start_thread, &semaphore);
 | 
				
			||||||
  pthread_attr_destroy(&attr);
 | 
					  pthread_attr_destroy(&attr);
 | 
				
			||||||
@@ -143,99 +141,3 @@ static void BM_semaphore_sem_post(int iters) {
 | 
				
			|||||||
    sched_yield();
 | 
					    sched_yield();
 | 
				
			||||||
  } while (!BM_semaphore_sem_post_running);
 | 
					  } while (!BM_semaphore_sem_post_running);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_semaphore_sem_post);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *    This test reports the overhead of sem_post to sem_wake. A circle of
 | 
					 | 
				
			||||||
 * num_semaphore - 1 threads are run on a set of semaphores to measure the
 | 
					 | 
				
			||||||
 * activity. One can calculate the sem_wake overhead alone by:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * BM_semaphore_sem_post_sem_wait - BM_semaphore_sem_post - BM_time_clock_gettime
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Differences will result if there are more threads than active processors,
 | 
					 | 
				
			||||||
 * there will be delay induced when scheduling the processes. This cost is
 | 
					 | 
				
			||||||
 * measured by trying different values of num_semaphore. The governor selected
 | 
					 | 
				
			||||||
 * will have a major impact on the results for a large number of threads.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *     To reduce the chances for threads racing ahead and not triggering the
 | 
					 | 
				
			||||||
 * futex, for example the background threads finish their job before the
 | 
					 | 
				
			||||||
 * sem_wait is hit in the main thread, the background threads will run at
 | 
					 | 
				
			||||||
 * batch priority and the main thread at fifo priority. This should generally
 | 
					 | 
				
			||||||
 * guarantee the main thread completes its task of priming itself with the
 | 
					 | 
				
			||||||
 * sem_wait before the other threads can start. In practice without the
 | 
					 | 
				
			||||||
 * sched mechanics here, this works on Android configured kernels, this is
 | 
					 | 
				
			||||||
 * insurance for wacky(tm) sched configurations.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void *BM_semaphore_sem_post_sem_wait_start_thread(void *obj) {
 | 
					 | 
				
			||||||
  sem_t *semaphore = reinterpret_cast<sem_t *>(obj);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  while ((BM_semaphore_sem_post_running > 0) && !sem_wait(semaphore)) {
 | 
					 | 
				
			||||||
    sem_post(semaphore + 1);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  --BM_semaphore_sem_post_running;
 | 
					 | 
				
			||||||
  return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_semaphore_sem_post_sem_wait_num(int iters, int num_semaphore) {
 | 
					 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  sem_t semaphore[num_semaphore];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (int i = 0; i < num_semaphore; ++i) {
 | 
					 | 
				
			||||||
    sem_init(semaphore + i, 0, 0);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pthread_attr_t attr;
 | 
					 | 
				
			||||||
  pthread_attr_init(&attr);
 | 
					 | 
				
			||||||
  BM_semaphore_sem_post_running = 1;
 | 
					 | 
				
			||||||
  struct sched_param param = { 0, };
 | 
					 | 
				
			||||||
  pthread_attr_setschedparam(&attr, ¶m);
 | 
					 | 
				
			||||||
  pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
 | 
					 | 
				
			||||||
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 | 
					 | 
				
			||||||
#ifdef PTHREAD_SET_INHERIT_SCHED
 | 
					 | 
				
			||||||
  pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  for (int i = 0; i < (num_semaphore - 1); ++i) {
 | 
					 | 
				
			||||||
    pthread_t pthread;
 | 
					 | 
				
			||||||
    pthread_create(&pthread, &attr, BM_semaphore_sem_post_sem_wait_start_thread, semaphore + i);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  pthread_attr_destroy(&attr);
 | 
					 | 
				
			||||||
  sched_yield();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  param.sched_priority = 1;
 | 
					 | 
				
			||||||
  sched_setscheduler((pid_t)0, SCHED_FIFO, ¶m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (int i = 0; i < iters; i += num_semaphore) {
 | 
					 | 
				
			||||||
    sem_post(semaphore);
 | 
					 | 
				
			||||||
    sem_wait(semaphore + num_semaphore - 1);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  param.sched_priority = 0;
 | 
					 | 
				
			||||||
  sched_setscheduler((pid_t)0, SCHED_OTHER, ¶m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (BM_semaphore_sem_post_running > 0) {
 | 
					 | 
				
			||||||
    BM_semaphore_sem_post_running = 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  for (int i = 0;
 | 
					 | 
				
			||||||
       (i < (10 * num_semaphore)) && (BM_semaphore_sem_post_running > (1 - num_semaphore));
 | 
					 | 
				
			||||||
       ++i) {
 | 
					 | 
				
			||||||
    for (int j = 0; j < (num_semaphore - 1); ++j) {
 | 
					 | 
				
			||||||
      sem_post(semaphore + j);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    sched_yield();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_semaphore_sem_post_sem_wait_low(int iters) {
 | 
					 | 
				
			||||||
    BM_semaphore_sem_post_sem_wait_num(iters, 2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_semaphore_sem_post_sem_wait_low);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void BM_semaphore_sem_post_sem_wait_high(int iters) {
 | 
					 | 
				
			||||||
    BM_semaphore_sem_post_sem_wait_num(iters, 100);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
BENCHMARK(BM_semaphore_sem_post_sem_wait_high);
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,11 +14,11 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdio_ext.h>
 | 
					#include <stdio_ext.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define KB 1024
 | 
					#define KB 1024
 | 
				
			||||||
#define MB 1024*KB
 | 
					#define MB 1024*KB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,12 +27,12 @@
 | 
				
			|||||||
    Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB)
 | 
					    Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename Fn>
 | 
					template <typename Fn>
 | 
				
			||||||
static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
 | 
					void ReadWriteTest(::testing::Benchmark* benchmark, int iters, int chunk_size, Fn f, bool buffered) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  benchmark->StopBenchmarkTiming();
 | 
				
			||||||
  FILE* fp = fopen("/dev/zero", "rw");
 | 
					  FILE* fp = fopen("/dev/zero", "rw");
 | 
				
			||||||
  __fsetlocking(fp, FSETLOCKING_BYCALLER);
 | 
					  __fsetlocking(fp, FSETLOCKING_BYCALLER);
 | 
				
			||||||
  char* buf = new char[chunk_size];
 | 
					  char* buf = new char[chunk_size];
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  benchmark->StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!buffered) {
 | 
					  if (!buffered) {
 | 
				
			||||||
    setvbuf(fp, 0, _IONBF, 0);
 | 
					    setvbuf(fp, 0, _IONBF, 0);
 | 
				
			||||||
@@ -42,31 +42,31 @@ static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
 | 
				
			|||||||
    f(buf, chunk_size, 1, fp);
 | 
					    f(buf, chunk_size, 1, fp);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  benchmark->StopBenchmarkTiming();
 | 
				
			||||||
  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
 | 
					  benchmark->SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
 | 
				
			||||||
  delete[] buf;
 | 
					  delete[] buf;
 | 
				
			||||||
  fclose(fp);
 | 
					  fclose(fp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_stdio_fread(int iters, int chunk_size) {
 | 
					BENCHMARK_WITH_ARG(BM_stdio_fread, int)->AT_COMMON_SIZES;
 | 
				
			||||||
  ReadWriteTest(iters, chunk_size, fread, true);
 | 
					void BM_stdio_fread::Run(int iters, int chunk_size) {
 | 
				
			||||||
 | 
					  ReadWriteTest(this, iters, chunk_size, fread, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_stdio_fread)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_stdio_fwrite(int iters, int chunk_size) {
 | 
					BENCHMARK_WITH_ARG(BM_stdio_fwrite, int)->AT_COMMON_SIZES;
 | 
				
			||||||
  ReadWriteTest(iters, chunk_size, fwrite, true);
 | 
					void BM_stdio_fwrite::Run(int iters, int chunk_size) {
 | 
				
			||||||
 | 
					  ReadWriteTest(this, iters, chunk_size, fwrite, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_stdio_fwrite)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_stdio_fread_unbuffered(int iters, int chunk_size) {
 | 
					BENCHMARK_WITH_ARG(BM_stdio_fread_unbuffered, int)->AT_COMMON_SIZES;
 | 
				
			||||||
  ReadWriteTest(iters, chunk_size, fread, false);
 | 
					void BM_stdio_fread_unbuffered::Run(int iters, int chunk_size) {
 | 
				
			||||||
 | 
					  ReadWriteTest(this, iters, chunk_size, fread, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_stdio_fread_unbuffered)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_stdio_fwrite_unbuffered(int iters, int chunk_size) {
 | 
					BENCHMARK_WITH_ARG(BM_stdio_fwrite_unbuffered, int)->AT_COMMON_SIZES;
 | 
				
			||||||
  ReadWriteTest(iters, chunk_size, fwrite, false);
 | 
					void BM_stdio_fwrite_unbuffered::Run(int iters, int chunk_size) {
 | 
				
			||||||
 | 
					  ReadWriteTest(this, iters, chunk_size, fwrite, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void FopenFgetsFclose(int iters, bool no_locking) {
 | 
					static void FopenFgetsFclose(int iters, bool no_locking) {
 | 
				
			||||||
  char buf[1024];
 | 
					  char buf[1024];
 | 
				
			||||||
@@ -78,12 +78,16 @@ static void FopenFgetsFclose(int iters, bool no_locking) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_stdio_fopen_fgets_fclose_locking(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_stdio_fopen_fgets_fclose_locking);
 | 
				
			||||||
 | 
					void BM_stdio_fopen_fgets_fclose_locking::Run(int iters) {
 | 
				
			||||||
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
  FopenFgetsFclose(iters, false);
 | 
					  FopenFgetsFclose(iters, false);
 | 
				
			||||||
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_stdio_fopen_fgets_fclose_locking);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_stdio_fopen_fgets_fclose_no_locking(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_stdio_fopen_fgets_fclose_no_locking);
 | 
				
			||||||
 | 
					void BM_stdio_fopen_fgets_fclose_no_locking::Run(int iters) {
 | 
				
			||||||
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
  FopenFgetsFclose(iters, true);
 | 
					  FopenFgetsFclose(iters, true);
 | 
				
			||||||
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,10 +14,11 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark.h"
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define KB 1024
 | 
					#define KB 1024
 | 
				
			||||||
#define MB 1024*KB
 | 
					#define MB 1024*KB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,7 +27,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// TODO: test unaligned operation too? (currently everything will be 8-byte aligned by malloc.)
 | 
					// TODO: test unaligned operation too? (currently everything will be 8-byte aligned by malloc.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_string_memcmp(int iters, int nbytes) {
 | 
					BENCHMARK_WITH_ARG(BM_string_memcmp, int)->AT_COMMON_SIZES;
 | 
				
			||||||
 | 
					void BM_string_memcmp::Run(int iters, int nbytes) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  char* src = new char[nbytes]; char* dst = new char[nbytes];
 | 
					  char* src = new char[nbytes]; char* dst = new char[nbytes];
 | 
				
			||||||
  memset(src, 'x', nbytes);
 | 
					  memset(src, 'x', nbytes);
 | 
				
			||||||
@@ -39,13 +41,13 @@ static void BM_string_memcmp(int iters, int nbytes) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
 | 
					  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
 | 
				
			||||||
  delete[] src;
 | 
					  delete[] src;
 | 
				
			||||||
  delete[] dst;
 | 
					  delete[] dst;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_string_memcmp)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_string_memcpy(int iters, int nbytes) {
 | 
					BENCHMARK_WITH_ARG(BM_string_memcpy, int)->AT_COMMON_SIZES;
 | 
				
			||||||
 | 
					void BM_string_memcpy::Run(int iters, int nbytes) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  char* src = new char[nbytes]; char* dst = new char[nbytes];
 | 
					  char* src = new char[nbytes]; char* dst = new char[nbytes];
 | 
				
			||||||
  memset(src, 'x', nbytes);
 | 
					  memset(src, 'x', nbytes);
 | 
				
			||||||
@@ -56,13 +58,13 @@ static void BM_string_memcpy(int iters, int nbytes) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
 | 
					  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
 | 
				
			||||||
  delete[] src;
 | 
					  delete[] src;
 | 
				
			||||||
  delete[] dst;
 | 
					  delete[] dst;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_string_memcpy)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_string_memmove(int iters, int nbytes) {
 | 
					BENCHMARK_WITH_ARG(BM_string_memmove, int)->AT_COMMON_SIZES;
 | 
				
			||||||
 | 
					void BM_string_memmove::Run(int iters, int nbytes) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  char* buf = new char[nbytes + 64];
 | 
					  char* buf = new char[nbytes + 64];
 | 
				
			||||||
  memset(buf, 'x', nbytes + 64);
 | 
					  memset(buf, 'x', nbytes + 64);
 | 
				
			||||||
@@ -73,12 +75,12 @@ static void BM_string_memmove(int iters, int nbytes) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
 | 
					  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
 | 
				
			||||||
  delete[] buf;
 | 
					  delete[] buf;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_string_memmove)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_string_memset(int iters, int nbytes) {
 | 
					BENCHMARK_WITH_ARG(BM_string_memset, int)->AT_COMMON_SIZES;
 | 
				
			||||||
 | 
					void BM_string_memset::Run(int iters, int nbytes) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  char* dst = new char[nbytes];
 | 
					  char* dst = new char[nbytes];
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
@@ -88,12 +90,12 @@ static void BM_string_memset(int iters, int nbytes) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
 | 
					  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
 | 
				
			||||||
  delete[] dst;
 | 
					  delete[] dst;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_string_memset)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_string_strlen(int iters, int nbytes) {
 | 
					BENCHMARK_WITH_ARG(BM_string_strlen, int)->AT_COMMON_SIZES;
 | 
				
			||||||
 | 
					void BM_string_strlen::Run(int iters, int nbytes) {
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  char* s = new char[nbytes];
 | 
					  char* s = new char[nbytes];
 | 
				
			||||||
  memset(s, 'x', nbytes);
 | 
					  memset(s, 'x', nbytes);
 | 
				
			||||||
@@ -106,7 +108,6 @@ static void BM_string_strlen(int iters, int nbytes) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(nbytes));
 | 
					  SetBenchmarkBytesProcessed(uint64_t(iters) * uint64_t(nbytes));
 | 
				
			||||||
  delete[] s;
 | 
					  delete[] s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_string_strlen)->AT_COMMON_SIZES;
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,14 +14,14 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <sys/syscall.h>
 | 
					#include <sys/syscall.h>
 | 
				
			||||||
#include <sys/time.h>
 | 
					#include <sys/time.h>
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_time_clock_gettime(int iters) {
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BENCHMARK_NO_ARG(BM_time_clock_gettime);
 | 
				
			||||||
 | 
					void BM_time_clock_gettime::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  timespec t;
 | 
					  timespec t;
 | 
				
			||||||
@@ -31,9 +31,9 @@ static void BM_time_clock_gettime(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_time_clock_gettime);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_time_clock_gettime_syscall(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_time_clock_gettime_syscall);
 | 
				
			||||||
 | 
					void BM_time_clock_gettime_syscall::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  timespec t;
 | 
					  timespec t;
 | 
				
			||||||
@@ -43,9 +43,9 @@ static void BM_time_clock_gettime_syscall(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_time_clock_gettime_syscall);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_time_gettimeofday(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_time_gettimeofday);
 | 
				
			||||||
 | 
					void BM_time_gettimeofday::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  timeval tv;
 | 
					  timeval tv;
 | 
				
			||||||
@@ -55,9 +55,9 @@ static void BM_time_gettimeofday(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_time_gettimeofday);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_time_gettimeofday_syscall(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_time_gettimeofday_syscall);
 | 
				
			||||||
 | 
					void BM_time_gettimeofday_syscall::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  timeval tv;
 | 
					  timeval tv;
 | 
				
			||||||
@@ -67,9 +67,9 @@ static void BM_time_gettimeofday_syscall(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_time_gettimeofday_syscall);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_time_time(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_time_time);
 | 
				
			||||||
 | 
					void BM_time_time::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
@@ -78,4 +78,3 @@ static void BM_time_time(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_time_time);
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,12 +14,13 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "benchmark.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/syscall.h>
 | 
					#include <sys/syscall.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_unistd_getpid(int iters) {
 | 
					#include <benchmark/Benchmark.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BENCHMARK_NO_ARG(BM_unistd_getpid);
 | 
				
			||||||
 | 
					void BM_unistd_getpid::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
@@ -28,9 +29,9 @@ static void BM_unistd_getpid(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_unistd_getpid);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_unistd_getpid_syscall(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_unistd_getpid_syscall);
 | 
				
			||||||
 | 
					void BM_unistd_getpid_syscall::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
@@ -39,14 +40,14 @@ static void BM_unistd_getpid_syscall(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_unistd_getpid_syscall);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__BIONIC__)
 | 
					#if defined(__BIONIC__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Stop GCC optimizing out our pure function.
 | 
					// Stop GCC optimizing out our pure function.
 | 
				
			||||||
/* Must not be static! */ pid_t (*gettid_fp)() = gettid;
 | 
					/* Must not be static! */ pid_t (*gettid_fp)() = gettid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_unistd_gettid(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_unistd_gettid);
 | 
				
			||||||
 | 
					void BM_unistd_gettid::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
@@ -55,11 +56,11 @@ static void BM_unistd_gettid(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_unistd_gettid);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void BM_unistd_gettid_syscall(int iters) {
 | 
					BENCHMARK_NO_ARG(BM_unistd_gettid_syscall);
 | 
				
			||||||
 | 
					void BM_unistd_gettid_syscall::Run(int iters) {
 | 
				
			||||||
  StartBenchmarkTiming();
 | 
					  StartBenchmarkTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < iters; ++i) {
 | 
					  for (int i = 0; i < iters; ++i) {
 | 
				
			||||||
@@ -68,4 +69,3 @@ static void BM_unistd_gettid_syscall(int iters) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  StopBenchmarkTiming();
 | 
					  StopBenchmarkTiming();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BENCHMARK(BM_unistd_gettid_syscall);
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										81
									
								
								benchmarks/utils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								benchmarks/utils.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2012 The Android Open Source Project
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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 <inttypes.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Round(int n) {
 | 
				
			||||||
 | 
					  int base = 1;
 | 
				
			||||||
 | 
					  while (base*10 < n) {
 | 
				
			||||||
 | 
					    base *= 10;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (n < 2*base) {
 | 
				
			||||||
 | 
					    return 2*base;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (n < 5*base) {
 | 
				
			||||||
 | 
					    return 5*base;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return 10*base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Similar to the code in art, but supporting both binary and decimal prefixes.
 | 
				
			||||||
 | 
					std::string PrettyInt(long value, size_t base) {
 | 
				
			||||||
 | 
					  if (base != 2 && base != 10) abort();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint64_t count = static_cast<uint64_t>(value);
 | 
				
			||||||
 | 
					  bool negative_number = false;
 | 
				
			||||||
 | 
					  if (value < 0) {
 | 
				
			||||||
 | 
					    negative_number = true;
 | 
				
			||||||
 | 
					    count = static_cast<uint64_t>(-value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // The byte thresholds at which we display amounts. A count is displayed
 | 
				
			||||||
 | 
					  // in unit U when kUnitThresholds[U] <= bytes < kUnitThresholds[U+1].
 | 
				
			||||||
 | 
					  static const uint64_t kUnitThresholds2[] = {
 | 
				
			||||||
 | 
					    1024*1024*1024 /* Gi */, 2*1024*1024 /* Mi */, 3*1024 /* Ki */, 0,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  static const uint64_t kUnitThresholds10[] = {
 | 
				
			||||||
 | 
					    1000*1000*1000 /* G */, 2*1000*1000 /* M */, 3*1000 /* k */, 0,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  static const uint64_t kAmountPerUnit2[] = { 1024*1024*1024, 1024*1024, 1024, 1 };
 | 
				
			||||||
 | 
					  static const uint64_t kAmountPerUnit10[] = { 1000*1000*1000, 1000*1000, 1000, 1 };
 | 
				
			||||||
 | 
					  static const char* const kUnitStrings2[] = { "Gi", "Mi", "Ki", "" };
 | 
				
			||||||
 | 
					  static const char* const kUnitStrings10[] = { "G", "M", "k", "" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Which set are we using?
 | 
				
			||||||
 | 
					  const uint64_t* kUnitThresholds = ((base == 2) ? kUnitThresholds2 : kUnitThresholds10);
 | 
				
			||||||
 | 
					  const uint64_t* kAmountPerUnit = ((base == 2) ? kAmountPerUnit2 : kAmountPerUnit10);
 | 
				
			||||||
 | 
					  const char* const* kUnitStrings = ((base == 2) ? kUnitStrings2 : kUnitStrings10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  size_t i = 0;
 | 
				
			||||||
 | 
					  for (; kUnitThresholds[i] != 0; ++i) {
 | 
				
			||||||
 | 
					    if (count >= kUnitThresholds[i]) {
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  char* s = NULL;
 | 
				
			||||||
 | 
					  asprintf(&s, "%s%" PRId64 "%s", (negative_number ? "-" : ""),
 | 
				
			||||||
 | 
					           count / kAmountPerUnit[i], kUnitStrings[i]);
 | 
				
			||||||
 | 
					  std::string result(s);
 | 
				
			||||||
 | 
					  free(s);
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								benchmarks/utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								benchmarks/utils.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2012 The Android Open Source Project
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef BENCHMARKS_UTILS_H
 | 
				
			||||||
 | 
					#define BENCHMARKS_UTILS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Round(int n);
 | 
				
			||||||
 | 
					std::string PrettyInt(long value, size_t base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // BENCHMARKS_UTILS_H
 | 
				
			||||||
		Reference in New Issue
	
	Block a user