Commit 4ce184d8 by Dominic Hamon

Code reformat

parent 80093519
...@@ -414,8 +414,8 @@ class Benchmark { ...@@ -414,8 +414,8 @@ class Benchmark {
static void RunInstance(const Instance& b, BenchmarkReporter* br); static void RunInstance(const Instance& b, BenchmarkReporter* br);
friend class ::benchmark::State; friend class ::benchmark::State;
friend struct ::benchmark::internal::Benchmark::Instance; friend struct ::benchmark::internal::Benchmark::Instance;
friend void ::benchmark::internal::RunMatchingBenchmarks( friend void ::benchmark::internal::RunMatchingBenchmarks(const std::string&,
const std::string&, BenchmarkReporter*); BenchmarkReporter*);
DISALLOW_COPY_AND_ASSIGN(Benchmark); DISALLOW_COPY_AND_ASSIGN(Benchmark);
}; };
...@@ -425,7 +425,7 @@ class Benchmark { ...@@ -425,7 +425,7 @@ class Benchmark {
struct BenchmarkContextData { struct BenchmarkContextData {
int num_cpus; int num_cpus;
double mhz_per_cpu; double mhz_per_cpu;
//std::string cpu_info; // std::string cpu_info;
bool cpu_scaling_enabled; bool cpu_scaling_enabled;
// The number of chars in the longest benchmark name. // The number of chars in the longest benchmark name.
...@@ -433,8 +433,8 @@ struct BenchmarkContextData { ...@@ -433,8 +433,8 @@ struct BenchmarkContextData {
}; };
struct BenchmarkRunData { struct BenchmarkRunData {
BenchmarkRunData() : BenchmarkRunData()
thread_index(-1), : thread_index(-1),
iterations(1), iterations(1),
real_accumulated_time(0), real_accumulated_time(0),
cpu_accumulated_time(0), cpu_accumulated_time(0),
...@@ -481,15 +481,13 @@ class BenchmarkReporter { ...@@ -481,15 +481,13 @@ class BenchmarkReporter {
virtual ~BenchmarkReporter(); virtual ~BenchmarkReporter();
}; };
// ------------------------------------------------------ // ------------------------------------------------------
// Internal implementation details follow; please ignore // Internal implementation details follow; please ignore
// Given a collection of reports, computes their mean and stddev. // Given a collection of reports, computes their mean and stddev.
// REQUIRES: all runs in "reports" must be from the same benchmark. // REQUIRES: all runs in "reports" must be from the same benchmark.
void ComputeStats(const std::vector<BenchmarkRunData>& reports, void ComputeStats(const std::vector<BenchmarkRunData>& reports,
BenchmarkRunData* mean_data, BenchmarkRunData* mean_data, BenchmarkRunData* stddev_data);
BenchmarkRunData* stddev_data);
// Simple reporter that outputs benchmark data to the console. This is the // Simple reporter that outputs benchmark data to the console. This is the
// default reporter used by RunSpecifiedBenchmarks(). // default reporter used by RunSpecifiedBenchmarks().
...@@ -497,6 +495,7 @@ class ConsoleReporter : public BenchmarkReporter { ...@@ -497,6 +495,7 @@ class ConsoleReporter : public BenchmarkReporter {
public: public:
virtual bool ReportContext(const BenchmarkContextData& context); virtual bool ReportContext(const BenchmarkContextData& context);
virtual void ReportRuns(const std::vector<BenchmarkRunData>& reports); virtual void ReportRuns(const std::vector<BenchmarkRunData>& reports);
private: private:
std::string PrintMemoryUsage(double bytes); std::string PrintMemoryUsage(double bytes);
virtual void PrintRunData(const BenchmarkRunData& report); virtual void PrintRunData(const BenchmarkRunData& report);
...@@ -513,11 +512,11 @@ void Initialize(int* argc, const char** argv); ...@@ -513,11 +512,11 @@ void Initialize(int* argc, const char** argv);
// Helpers for generating unique variable names // Helpers for generating unique variable names
#define BENCHMARK_CONCAT(a, b, c) BENCHMARK_CONCAT2(a, b, c) #define BENCHMARK_CONCAT(a, b, c) BENCHMARK_CONCAT2(a, b, c)
#define BENCHMARK_CONCAT2(a, b, c) a ## b ## c #define BENCHMARK_CONCAT2(a, b, c) a##b##c
#define BENCHMARK(n) \ #define BENCHMARK(n) \
static ::benchmark::internal::Benchmark* \ static ::benchmark::internal::Benchmark* BENCHMARK_CONCAT( \
BENCHMARK_CONCAT(__benchmark_, n, __LINE__) ATTRIBUTE_UNUSED = \ __benchmark_, n, __LINE__) ATTRIBUTE_UNUSED = \
(new ::benchmark::internal::Benchmark(#n, n)) (new ::benchmark::internal::Benchmark(#n, n))
// Old-style macros // Old-style macros
...@@ -536,13 +535,13 @@ void Initialize(int* argc, const char** argv); ...@@ -536,13 +535,13 @@ void Initialize(int* argc, const char** argv);
// //
// will register BM_Foo<1> as a benchmark. // will register BM_Foo<1> as a benchmark.
#define BENCHMARK_TEMPLATE(n, a) \ #define BENCHMARK_TEMPLATE(n, a) \
static ::benchmark::internal::Benchmark* \ static ::benchmark::internal::Benchmark* BENCHMARK_CONCAT( \
BENCHMARK_CONCAT(__benchmark_, n, __LINE__) ATTRIBUTE_UNUSED = \ __benchmark_, n, __LINE__) ATTRIBUTE_UNUSED = \
(new ::benchmark::internal::Benchmark(#n "<" #a ">", n<a>)) (new ::benchmark::internal::Benchmark(#n "<" #a ">", n<a>))
#define BENCHMARK_TEMPLATE2(n, a, b) \ #define BENCHMARK_TEMPLATE2(n, a, b) \
static ::benchmark::internal::Benchmark* \ static ::benchmark::internal::Benchmark* BENCHMARK_CONCAT( \
BENCHMARK_CONCAT(__benchmark_, n, __LINE__) ATTRIBUTE_UNUSED = \ __benchmark_, n, __LINE__) ATTRIBUTE_UNUSED = \
(new ::benchmark::internal::Benchmark(#n "<" #a "," #b ">", n<a, b>)) (new ::benchmark::internal::Benchmark(#n "<" #a "," #b ">", n<a, b>))
#endif // BENCHMARK_BENCHMARK_H_ #endif // BENCHMARK_BENCHMARK_H_
......
...@@ -34,7 +34,10 @@ char (&ArraySizeHelper(const T (&array)[N]))[N]; ...@@ -34,7 +34,10 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array))) #define arraysize(array) (sizeof(ArraySizeHelper(array)))
#define CHECK(b) do { if (!(b)) assert(false); } while(0) #define CHECK(b) \
do { \
if (!(b)) assert(false); \
} while (0)
#define CHECK_EQ(a, b) CHECK((a) == (b)) #define CHECK_EQ(a, b) CHECK((a) == (b))
#define CHECK_NE(a, b) CHECK((a) != (b)) #define CHECK_NE(a, b) CHECK((a) != (b))
#define CHECK_GE(a, b) CHECK((a) >= (b)) #define CHECK_GE(a, b) CHECK((a) >= (b))
...@@ -45,14 +48,14 @@ char (&ArraySizeHelper(const T (&array)[N]))[N]; ...@@ -45,14 +48,14 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
// //
// Prevent the compiler from complaining about or optimizing away variables // Prevent the compiler from complaining about or optimizing away variables
// that appear unused. // that appear unused.
#define ATTRIBUTE_UNUSED __attribute__ ((unused)) #define ATTRIBUTE_UNUSED __attribute__((unused))
// //
// For functions we want to force inline or not inline. // For functions we want to force inline or not inline.
// Introduced in gcc 3.1. // Introduced in gcc 3.1.
#define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) #define ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
#define HAVE_ATTRIBUTE_ALWAYS_INLINE 1 #define HAVE_ATTRIBUTE_ALWAYS_INLINE 1
#define ATTRIBUTE_NOINLINE __attribute__ ((noinline)) #define ATTRIBUTE_NOINLINE __attribute__((noinline))
#define HAVE_ATTRIBUTE_NOINLINE 1 #define HAVE_ATTRIBUTE_NOINLINE 1
#endif // BENCHMARK_MACROS_H_ #endif // BENCHMARK_MACROS_H_
...@@ -58,14 +58,14 @@ DEFINE_bool(color_print, true, "Enables colorized logging."); ...@@ -58,14 +58,14 @@ DEFINE_bool(color_print, true, "Enables colorized logging.");
DECLARE_string(heap_check); DECLARE_string(heap_check);
// The ""'s catch people who don't pass in a literal for "str" // The ""'s catch people who don't pass in a literal for "str"
#define strliterallen(str) (sizeof("" str "")-1) #define strliterallen(str) (sizeof("" str "") - 1)
// Must use a string literal for prefix. // Must use a string literal for prefix.
#define memprefix(str, len, prefix) \ #define memprefix(str, len, prefix) \
( (((len) >= strliterallen(prefix)) \ ((((len) >= strliterallen(prefix)) && \
&& memcmp(str, prefix, strliterallen(prefix)) == 0) \ memcmp(str, prefix, strliterallen(prefix)) == 0) \
? str + strliterallen(prefix) \ ? str + strliterallen(prefix) \
: NULL ) : NULL)
namespace benchmark { namespace benchmark {
namespace { namespace {
...@@ -83,9 +83,8 @@ static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits), ...@@ -83,9 +83,8 @@ static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),
"Small SI and Big SI unit arrays must be the same size"); "Small SI and Big SI unit arrays must be the same size");
static const int kUnitsSize = arraysize(kBigSIUnits); static const int kUnitsSize = arraysize(kBigSIUnits);
void ToExponentAndMantissa(double val, double thresh, void ToExponentAndMantissa(double val, double thresh, int precision,
int precision, double one_k, double one_k, std::string* mantissa, int* exponent) {
std::string* mantissa, int* exponent) {
std::stringstream mantissa_stream; std::stringstream mantissa_stream;
if (val < 0) { if (val < 0) {
...@@ -136,15 +135,13 @@ void ToExponentAndMantissa(double val, double thresh, ...@@ -136,15 +135,13 @@ void ToExponentAndMantissa(double val, double thresh,
} }
std::string ExponentToPrefix(int exponent, bool iec) { std::string ExponentToPrefix(int exponent, bool iec) {
if (exponent == 0) if (exponent == 0) return "";
return "";
const int index = (exponent > 0 ? exponent - 1 : -exponent - 1); const int index = (exponent > 0 ? exponent - 1 : -exponent - 1);
if (index >= kUnitsSize) if (index >= kUnitsSize) return "";
return "";
const char *array = (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : const char* array =
kSmallSIUnits); (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits);
if (iec) if (iec)
return array[index] + std::string("i"); return array[index] + std::string("i");
else else
...@@ -207,7 +204,7 @@ const char* Prefix() { ...@@ -207,7 +204,7 @@ const char* Prefix() {
} }
// TODO // TODO
//static internal::MallocCounter *benchmark_mc; // static internal::MallocCounter *benchmark_mc;
bool CpuScalingEnabled() { bool CpuScalingEnabled() {
// On Linux, the CPUfreq subsystem exposes CPU information as files on the // On Linux, the CPUfreq subsystem exposes CPU information as files on the
...@@ -218,13 +215,11 @@ bool CpuScalingEnabled() { ...@@ -218,13 +215,11 @@ bool CpuScalingEnabled() {
ss << "/sys/devices/system/cpu/cpu" << cpu << "/cpufreq/scaling_governor"; ss << "/sys/devices/system/cpu/cpu" << cpu << "/cpufreq/scaling_governor";
std::string governor_file = ss.str(); std::string governor_file = ss.str();
FILE* file = fopen(governor_file.c_str(), "r"); FILE* file = fopen(governor_file.c_str(), "r");
if (!file) if (!file) break;
break;
char buff[16]; char buff[16];
size_t bytes_read = fread(buff, 1, sizeof(buff), file); size_t bytes_read = fread(buff, 1, sizeof(buff), file);
fclose(file); fclose(file);
if (memprefix(buff, bytes_read, "performance") == NULL) if (memprefix(buff, bytes_read, "performance") == NULL) return true;
return true;
} }
return false; return false;
} }
...@@ -236,8 +231,7 @@ namespace internal { ...@@ -236,8 +231,7 @@ namespace internal {
BenchmarkReporter::~BenchmarkReporter() {} BenchmarkReporter::~BenchmarkReporter() {}
void ComputeStats(const std::vector<BenchmarkRunData>& reports, void ComputeStats(const std::vector<BenchmarkRunData>& reports,
BenchmarkRunData* mean_data, BenchmarkRunData* mean_data, BenchmarkRunData* stddev_data) {
BenchmarkRunData* stddev_data) {
// Accumulators. // Accumulators.
Stat1_d real_accumulated_time_stat; Stat1_d real_accumulated_time_stat;
Stat1_d cpu_accumulated_time_stat; Stat1_d cpu_accumulated_time_stat;
...@@ -257,8 +251,8 @@ void ComputeStats(const std::vector<BenchmarkRunData>& reports, ...@@ -257,8 +251,8 @@ void ComputeStats(const std::vector<BenchmarkRunData>& reports,
items_per_second_stat += Stat1_d(it->items_per_second, it->iterations); items_per_second_stat += Stat1_d(it->items_per_second, it->iterations);
bytes_per_second_stat += Stat1_d(it->bytes_per_second, it->iterations); bytes_per_second_stat += Stat1_d(it->bytes_per_second, it->iterations);
iterations_stat += Stat1_d(it->iterations, it->iterations); iterations_stat += Stat1_d(it->iterations, it->iterations);
max_heapbytes_used_stat += Stat1MinMax_d(it->max_heapbytes_used, max_heapbytes_used_stat +=
it->iterations); Stat1MinMax_d(it->max_heapbytes_used, it->iterations);
} }
// Get the data from the accumulator to BenchmarkRunData's. // Get the data from the accumulator to BenchmarkRunData's.
...@@ -268,7 +262,7 @@ void ComputeStats(const std::vector<BenchmarkRunData>& reports, ...@@ -268,7 +262,7 @@ void ComputeStats(const std::vector<BenchmarkRunData>& reports,
mean_data->cpu_accumulated_time = cpu_accumulated_time_stat.Mean(); mean_data->cpu_accumulated_time = cpu_accumulated_time_stat.Mean();
mean_data->bytes_per_second = bytes_per_second_stat.Mean(); mean_data->bytes_per_second = bytes_per_second_stat.Mean();
mean_data->items_per_second = items_per_second_stat.Mean(); mean_data->items_per_second = items_per_second_stat.Mean();
mean_data->max_heapbytes_used = max_heapbytes_used_stat.Max(); mean_data->max_heapbytes_used = max_heapbytes_used_stat.max();
// Only add label to mean/stddev if it is same for all runs // Only add label to mean/stddev if it is same for all runs
mean_data->report_label = reports[0].report_label; mean_data->report_label = reports[0].report_label;
...@@ -290,8 +284,7 @@ void ComputeStats(const std::vector<BenchmarkRunData>& reports, ...@@ -290,8 +284,7 @@ void ComputeStats(const std::vector<BenchmarkRunData>& reports,
} }
std::string ConsoleReporter::PrintMemoryUsage(double bytes) { std::string ConsoleReporter::PrintMemoryUsage(double bytes) {
if (!get_memory_usage || bytes < 0.0) if (!get_memory_usage || bytes < 0.0) return "";
return "";
std::stringstream ss; std::stringstream ss;
ss << " " << HumanReadableNumber(bytes) << "B peak-mem"; ss << " " << HumanReadableNumber(bytes) << "B peak-mem";
...@@ -311,8 +304,8 @@ bool ConsoleReporter::ReportContext(const BenchmarkContextData& context) { ...@@ -311,8 +304,8 @@ bool ConsoleReporter::ReportContext(const BenchmarkContextData& context) {
&remainder_ms) << "\n"; &remainder_ms) << "\n";
// Show details of CPU model, caches, TLBs etc. // Show details of CPU model, caches, TLBs etc.
// if (!context.cpu_info.empty()) // if (!context.cpu_info.empty())
// std::cout << "CPU: " << context.cpu_info.c_str(); // std::cout << "CPU: " << context.cpu_info.c_str();
if (context.cpu_scaling_enabled) { if (context.cpu_scaling_enabled) {
std::cerr << "CPU scaling is enabled: Benchmark timings may be noisy.\n"; std::cerr << "CPU scaling is enabled: Benchmark timings may be noisy.\n";
...@@ -334,8 +327,7 @@ void ConsoleReporter::ReportRuns(const std::vector<BenchmarkRunData>& reports) { ...@@ -334,8 +327,7 @@ void ConsoleReporter::ReportRuns(const std::vector<BenchmarkRunData>& reports) {
} }
// We don't report aggregated data if there was a single run. // We don't report aggregated data if there was a single run.
if (reports.size() < 2) if (reports.size() < 2) return;
return;
BenchmarkRunData mean_data; BenchmarkRunData mean_data;
BenchmarkRunData stddev_data; BenchmarkRunData stddev_data;
...@@ -379,22 +371,21 @@ void ConsoleReporter::PrintRunData(const BenchmarkRunData& result) { ...@@ -379,22 +371,21 @@ void ConsoleReporter::PrintRunData(const BenchmarkRunData& result) {
} }
void MemoryUsage() { void MemoryUsage() {
//if (benchmark_mc) { // if (benchmark_mc) {
// benchmark_mc->Reset(); // benchmark_mc->Reset();
//} else { //} else {
get_memory_usage = true; get_memory_usage = true;
//} //}
} }
void UseRealTime() { void UseRealTime() { use_real_time = true; }
use_real_time = true;
}
void PrintUsageAndExit() { void PrintUsageAndExit() {
fprintf(stdout, "benchmark [--benchmark_filter=<regex>]\n" fprintf(stdout,
"benchmark [--benchmark_filter=<regex>]\n"
" [--benchmark_iterations=<iterations>]\n" " [--benchmark_iterations=<iterations>]\n"
" [--benchmark_min_time=<min_time>]\n" " [--benchmark_min_time=<min_time>]\n"
// " [--benchmark_memory_usage]\n" //" [--benchmark_memory_usage]\n"
" [--benchmark_repetitions=<num_repetitions>]\n" " [--benchmark_repetitions=<num_repetitions>]\n"
" [--color_print={true|false}]\n" " [--color_print={true|false}]\n"
" [--v=<verbosity>]\n"); " [--v=<verbosity>]\n");
...@@ -403,21 +394,19 @@ void PrintUsageAndExit() { ...@@ -403,21 +394,19 @@ void PrintUsageAndExit() {
void ParseCommandLineFlags(int* argc, const char** argv) { void ParseCommandLineFlags(int* argc, const char** argv) {
for (int i = 1; i < *argc; ++i) { for (int i = 1; i < *argc; ++i) {
if (ParseStringFlag(argv[i], "benchmark_filter", if (ParseStringFlag(argv[i], "benchmark_filter", &FLAGS_benchmark_filter) ||
&FLAGS_benchmark_filter) ||
ParseInt32Flag(argv[i], "benchmark_iterations", ParseInt32Flag(argv[i], "benchmark_iterations",
&FLAGS_benchmark_iterations) || &FLAGS_benchmark_iterations) ||
ParseDoubleFlag(argv[i], "benchmark_min_time", ParseDoubleFlag(argv[i], "benchmark_min_time",
&FLAGS_benchmark_min_time) || &FLAGS_benchmark_min_time) ||
// TODO(dominic) // TODO(dominic)
// ParseBoolFlag(argv[i], "gbenchmark_memory_usage", // ParseBoolFlag(argv[i], "gbenchmark_memory_usage",
// &FLAGS_gbenchmark_memory_usage) || // &FLAGS_gbenchmark_memory_usage) ||
ParseInt32Flag(argv[i], "benchmark_repetitions", ParseInt32Flag(argv[i], "benchmark_repetitions",
&FLAGS_benchmark_repetitions) || &FLAGS_benchmark_repetitions) ||
ParseBoolFlag(argv[i], "color_print", &FLAGS_color_print) || ParseBoolFlag(argv[i], "color_print", &FLAGS_color_print) ||
ParseInt32Flag(argv[i], "v", &FLAGS_v)) { ParseInt32Flag(argv[i], "v", &FLAGS_v)) {
for (int j = i; j != *argc; ++j) for (int j = i; j != *argc; ++j) argv[j] = argv[j + 1];
argv[j] = argv[j + 1];
--(*argc); --(*argc);
--i; --i;
...@@ -431,9 +420,11 @@ void ParseCommandLineFlags(int* argc, const char** argv) { ...@@ -431,9 +420,11 @@ void ParseCommandLineFlags(int* argc, const char** argv) {
// A clock that provides a fast mechanism to check if we're nearly done. // A clock that provides a fast mechanism to check if we're nearly done.
class State::FastClock { class State::FastClock {
public: public:
enum Type { REAL_TIME, CPU_TIME }; enum Type {
explicit FastClock(Type type) REAL_TIME,
: type_(type), approx_time_(NowMicros()) { CPU_TIME
};
explicit FastClock(Type type) : type_(type), approx_time_(NowMicros()) {
sem_init(&bg_done_, 0, 0); sem_init(&bg_done_, 0, 0);
pthread_create(&bg_, NULL, &BGThreadWrapper, this); pthread_create(&bg_, NULL, &BGThreadWrapper, this);
} }
...@@ -449,7 +440,7 @@ class State::FastClock { ...@@ -449,7 +440,7 @@ class State::FastClock {
inline bool HasReached(int64_t when_micros) { inline bool HasReached(int64_t when_micros) {
return std::atomic_load(&approx_time_) >= when_micros; return std::atomic_load(&approx_time_) >= when_micros;
// NOTE: this is the same as we're dealing with an int64_t // NOTE: this is the same as we're dealing with an int64_t
//return (base::subtle::NoBarrier_Load(&approx_time_) >= when_micros); // return (base::subtle::NoBarrier_Load(&approx_time_) >= when_micros);
} }
// Returns the current time in microseconds past the epoch. // Returns the current time in microseconds past the epoch.
...@@ -493,7 +484,7 @@ class State::FastClock { ...@@ -493,7 +484,7 @@ class State::FastClock {
SleepForMicroseconds(1000); SleepForMicroseconds(1000);
std::atomic_store(&approx_time_, NowMicros()); std::atomic_store(&approx_time_, NowMicros());
// NOTE: same code but no memory barrier. think on it. // NOTE: same code but no memory barrier. think on it.
//base::subtle::Release_Store(&approx_time_, NowMicros()); // base::subtle::Release_Store(&approx_time_, NowMicros());
sem_getvalue(&bg_done_, &done); sem_getvalue(&bg_done_, &done);
} while (done == 0); } while (done == 0);
} }
...@@ -523,8 +514,12 @@ namespace internal { ...@@ -523,8 +514,12 @@ namespace internal {
// Information kept per benchmark we may want to run // Information kept per benchmark we may want to run
struct Benchmark::Instance { struct Benchmark::Instance {
Instance() Instance()
: bm(nullptr), threads(1), rangeXset(false), rangeX(kNoRange), : bm(nullptr),
rangeYset(false), rangeY(kNoRange) {} threads(1),
rangeXset(false),
rangeX(kNoRange),
rangeYset(false),
rangeY(kNoRange) {}
std::string name; std::string name;
Benchmark* bm; Benchmark* bm;
...@@ -551,14 +546,14 @@ struct State::SharedState { ...@@ -551,14 +546,14 @@ struct State::SharedState {
std::string label; std::string label;
explicit SharedState(const internal::Benchmark::Instance* b) explicit SharedState(const internal::Benchmark::Instance* b)
: instance(b), starting(0), stopping(0), : instance(b),
starting(0),
stopping(0),
threads(b == nullptr ? 1 : b->threads) { threads(b == nullptr ? 1 : b->threads) {
pthread_mutex_init(&mu, nullptr); pthread_mutex_init(&mu, nullptr);
} }
~SharedState() { ~SharedState() { pthread_mutex_destroy(&mu); }
pthread_mutex_destroy(&mu);
}
DISALLOW_COPY_AND_ASSIGN(SharedState); DISALLOW_COPY_AND_ASSIGN(SharedState);
}; };
...@@ -567,8 +562,7 @@ namespace internal { ...@@ -567,8 +562,7 @@ namespace internal {
Benchmark::Benchmark(const char* name, BenchmarkFunction f) Benchmark::Benchmark(const char* name, BenchmarkFunction f)
: name_(name), function_(f) { : name_(name), function_(f) {
mutex_lock l(&benchmark_mutex); mutex_lock l(&benchmark_mutex);
if (families == nullptr) if (families == nullptr) families = new std::vector<Benchmark*>();
families = new std::vector<Benchmark*>();
registration_index_ = families->size(); registration_index_ = families->size();
families->push_back(this); families->push_back(this);
} }
...@@ -578,8 +572,7 @@ Benchmark::~Benchmark() { ...@@ -578,8 +572,7 @@ Benchmark::~Benchmark() {
CHECK((*families)[registration_index_] == this); CHECK((*families)[registration_index_] == this);
(*families)[registration_index_] = NULL; (*families)[registration_index_] = NULL;
// Shrink the vector if convenient. // Shrink the vector if convenient.
while (!families->empty() && families->back() == NULL) while (!families->empty() && families->back() == NULL) families->pop_back();
families->pop_back();
} }
Benchmark* Benchmark::Arg(int x) { Benchmark* Benchmark::Arg(int x) {
...@@ -593,8 +586,7 @@ Benchmark* Benchmark::Range(int start, int limit) { ...@@ -593,8 +586,7 @@ Benchmark* Benchmark::Range(int start, int limit) {
AddRange(&arglist, start, limit, kRangeMultiplier); AddRange(&arglist, start, limit, kRangeMultiplier);
mutex_lock l(&benchmark_mutex); mutex_lock l(&benchmark_mutex);
for (size_t i = 0; i < arglist.size(); ++i) for (size_t i = 0; i < arglist.size(); ++i) rangeX_.push_back(arglist[i]);
rangeX_.push_back(arglist[i]);
return this; return this;
} }
...@@ -602,8 +594,7 @@ Benchmark* Benchmark::DenseRange(int start, int limit) { ...@@ -602,8 +594,7 @@ Benchmark* Benchmark::DenseRange(int start, int limit) {
CHECK_GE(start, 0); CHECK_GE(start, 0);
CHECK_LE(start, limit); CHECK_LE(start, limit);
mutex_lock l(&benchmark_mutex); mutex_lock l(&benchmark_mutex);
for (int arg = start; arg <= limit; ++arg) for (int arg = start; arg <= limit; ++arg) rangeX_.push_back(arg);
rangeX_.push_back(arg);
return this; return this;
} }
...@@ -662,14 +653,13 @@ void Benchmark::AddRange(std::vector<int>* dst, int lo, int hi, int mult) { ...@@ -662,14 +653,13 @@ void Benchmark::AddRange(std::vector<int>* dst, int lo, int hi, int mult) {
dst->push_back(lo); dst->push_back(lo);
// Now space out the benchmarks in multiples of "mult" // Now space out the benchmarks in multiples of "mult"
for (int32_t i = 1; i < std::numeric_limits<int32_t>::max()/mult; i *= mult) { for (int32_t i = 1; i < std::numeric_limits<int32_t>::max() / mult;
i *= mult) {
if (i >= hi) break; if (i >= hi) break;
if (i > lo) if (i > lo) dst->push_back(i);
dst->push_back(i);
} }
// Add "hi" (if different from "lo") // Add "hi" (if different from "lo")
if (hi != lo) if (hi != lo) dst->push_back(hi);
dst->push_back(hi);
} }
std::vector<Benchmark::Instance> Benchmark::CreateBenchmarkInstances( std::vector<Benchmark::Instance> Benchmark::CreateBenchmarkInstances(
...@@ -767,7 +757,8 @@ void Benchmark::MeasureOverhead() { ...@@ -767,7 +757,8 @@ void Benchmark::MeasureOverhead() {
State::FastClock clock(State::FastClock::CPU_TIME); State::FastClock clock(State::FastClock::CPU_TIME);
State::SharedState state(nullptr); State::SharedState state(nullptr);
State runner(&clock, &state, 0); State runner(&clock, &state, 0);
while (runner.KeepRunning()) {} while (runner.KeepRunning()) {
}
overhead = state.runs[0].real_accumulated_time / overhead = state.runs[0].real_accumulated_time /
static_cast<double>(state.runs[0].iterations); static_cast<double>(state.runs[0].iterations);
#ifdef DEBUG #ifdef DEBUG
...@@ -796,11 +787,10 @@ void Benchmark::RunInstance(const Instance& b, BenchmarkReporter* br) { ...@@ -796,11 +787,10 @@ void Benchmark::RunInstance(const Instance& b, BenchmarkReporter* br) {
runners[i]->Run(); runners[i]->Run();
} }
if (b.multithreaded()) { if (b.multithreaded()) {
for (int i = 0; i < b.threads; ++i) for (int i = 0; i < b.threads; ++i) runners[i]->Wait();
runners[i]->Wait();
} }
} }
/* /*
double mem_usage = 0; double mem_usage = 0;
if (get_memory_usage) { if (get_memory_usage) {
// Measure memory usage // Measure memory usage
...@@ -817,12 +807,12 @@ void Benchmark::RunInstance(const Instance& b, BenchmarkReporter* br) { ...@@ -817,12 +807,12 @@ void Benchmark::RunInstance(const Instance& b, BenchmarkReporter* br) {
mem_usage = mc.PeakHeapGrowth(); mem_usage = mc.PeakHeapGrowth();
} }
} }
*/ */
running_benchmark = false; running_benchmark = false;
for (internal::BenchmarkRunData& report : state.runs) { for (internal::BenchmarkRunData& report : state.runs) {
double seconds = (use_real_time ? report.real_accumulated_time : double seconds = (use_real_time ? report.real_accumulated_time
report.cpu_accumulated_time); : report.cpu_accumulated_time);
report.benchmark_name = b.name; report.benchmark_name = b.name;
report.report_label = state.label; report.report_label = state.label;
report.bytes_per_second = state.stats.bytes_processed / seconds; report.bytes_per_second = state.stats.bytes_processed / seconds;
...@@ -836,18 +826,17 @@ void Benchmark::RunInstance(const Instance& b, BenchmarkReporter* br) { ...@@ -836,18 +826,17 @@ void Benchmark::RunInstance(const Instance& b, BenchmarkReporter* br) {
// Run the specified benchmark, measure its peak memory usage, and // Run the specified benchmark, measure its peak memory usage, and
// return the peak memory usage. // return the peak memory usage.
double Benchmark::MeasurePeakHeapMemory(const Instance& b) { double Benchmark::MeasurePeakHeapMemory(const Instance& b) {
if (!get_memory_usage) if (!get_memory_usage) return 0.0;
return 0.0;
double bytes = 0.0; double bytes = 0.0;
/* TODO(dominich) /* TODO(dominich)
// Should we do multi-threaded runs? // Should we do multi-threaded runs?
const int num_threads = 1; const int num_threads = 1;
const int num_iters = 1; const int num_iters = 1;
{ {
// internal::MallocCounter mc(internal::MallocCounter::THIS_THREAD_ONLY); // internal::MallocCounter mc(internal::MallocCounter::THIS_THREAD_ONLY);
running_benchmark = true; running_benchmark = true;
timer_manager = new TimerManager(1, NULL); timer_manager = new TimerManager(1, NULL);
// benchmark_mc = &mc; // benchmark_mc = &mc;
timer_manager->StartTimer(); timer_manager->StartTimer();
b.Run(num_iters); b.Run(num_iters);
...@@ -855,8 +844,8 @@ double Benchmark::MeasurePeakHeapMemory(const Instance& b) { ...@@ -855,8 +844,8 @@ double Benchmark::MeasurePeakHeapMemory(const Instance& b) {
running_benchmark = false; running_benchmark = false;
delete timer_manager; delete timer_manager;
timer_manager = NULL; timer_manager = NULL;
// benchmark_mc = NULL; // benchmark_mc = NULL;
// bytes = mc.PeakHeapGrowth(); // bytes = mc.PeakHeapGrowth();
} }
*/ */
return bytes; return bytes;
...@@ -876,14 +865,13 @@ State::State(FastClock* clock, SharedState* s, int t) ...@@ -876,14 +865,13 @@ State::State(FastClock* clock, SharedState* s, int t)
start_pause_(0.0), start_pause_(0.0),
pause_time_(0.0), pause_time_(0.0),
total_iterations_(0), total_iterations_(0),
interval_micros_( interval_micros_(static_cast<int64_t>(kNumMicrosPerSecond *
static_cast<int64_t>(kNumMicrosPerSecond * FLAGS_benchmark_min_time / FLAGS_benchmark_min_time /
FLAGS_benchmark_repetitions)), FLAGS_benchmark_repetitions)),
is_continuation_(false), is_continuation_(false),
stats_(new ThreadStats()) { stats_(new ThreadStats()) {
CHECK(clock != nullptr); CHECK(clock != nullptr);
CHECK(s != nullptr); CHECK(s != nullptr);
} }
bool State::KeepRunning() { bool State::KeepRunning() {
...@@ -895,24 +883,27 @@ bool State::KeepRunning() { ...@@ -895,24 +883,27 @@ bool State::KeepRunning() {
return true; return true;
} }
switch(state_) { switch (state_) {
case STATE_INITIAL: return StartRunning(); case STATE_INITIAL:
case STATE_STARTING: CHECK(false); return true; return StartRunning();
case STATE_RUNNING: return FinishInterval(); case STATE_STARTING:
case STATE_STOPPING: return MaybeStop(); CHECK(false);
case STATE_STOPPED: CHECK(false); return true; return true;
case STATE_RUNNING:
return FinishInterval();
case STATE_STOPPING:
return MaybeStop();
case STATE_STOPPED:
CHECK(false);
return true;
} }
CHECK(false); CHECK(false);
return false; return false;
} }
void State::PauseTiming() { void State::PauseTiming() { start_pause_ = walltime::Now(); }
start_pause_ = walltime::Now();
}
void State::ResumeTiming() { void State::ResumeTiming() { pause_time_ += walltime::Now() - start_pause_; }
pause_time_ += walltime::Now() - start_pause_;
}
void State::SetBytesProcessed(int64_t bytes) { void State::SetBytesProcessed(int64_t bytes) {
CHECK_EQ(STATE_STOPPED, state_); CHECK_EQ(STATE_STOPPED, state_);
...@@ -964,8 +955,8 @@ bool State::StartRunning() { ...@@ -964,8 +955,8 @@ bool State::StartRunning() {
} }
if (last_thread) { if (last_thread) {
clock_->InitType( clock_->InitType(use_real_time ? FastClock::REAL_TIME
use_real_time ? FastClock::REAL_TIME : FastClock::CPU_TIME); : FastClock::CPU_TIME);
{ {
mutex_lock l(&starting_mutex); mutex_lock l(&starting_mutex);
pthread_cond_broadcast(&starting_cv); pthread_cond_broadcast(&starting_cv);
...@@ -1022,7 +1013,6 @@ bool State::FinishInterval() { ...@@ -1022,7 +1013,6 @@ bool State::FinishInterval() {
const double accumulated_time = walltime::Now() - start_time_; const double accumulated_time = walltime::Now() - start_time_;
const double total_overhead = overhead * iterations_; const double total_overhead = overhead * iterations_;
//const double total_overhead = 0.0;
CHECK_LT(pause_time_, accumulated_time); CHECK_LT(pause_time_, accumulated_time);
CHECK_LT(pause_time_ + total_overhead, accumulated_time); CHECK_LT(pause_time_ + total_overhead, accumulated_time);
data.real_accumulated_time = data.real_accumulated_time =
...@@ -1046,8 +1036,7 @@ bool State::FinishInterval() { ...@@ -1046,8 +1036,7 @@ bool State::FinishInterval() {
is_continuation_ = keep_going; is_continuation_ = keep_going;
} else { } else {
// If this is a repetition, run another interval as a new data point. // If this is a repetition, run another interval as a new data point.
keep_going = keep_going = shared_->runs.size() <
shared_->runs.size() <
static_cast<size_t>(FLAGS_benchmark_repetitions); static_cast<size_t>(FLAGS_benchmark_repetitions);
is_continuation_ = !keep_going; is_continuation_ = !keep_going;
} }
...@@ -1065,8 +1054,7 @@ bool State::FinishInterval() { ...@@ -1065,8 +1054,7 @@ bool State::FinishInterval() {
} }
} }
if (state_ == STATE_RUNNING) if (state_ == STATE_RUNNING) NewInterval();
NewInterval();
return keep_going; return keep_going;
} }
...@@ -1093,9 +1081,7 @@ void State::RunAsThread() { ...@@ -1093,9 +1081,7 @@ void State::RunAsThread() {
CHECK_EQ(0, pthread_create(&thread_, nullptr, &State::RunWrapper, this)); CHECK_EQ(0, pthread_create(&thread_, nullptr, &State::RunWrapper, this));
} }
void State::Wait() { void State::Wait() { CHECK_EQ(0, pthread_join(thread_, nullptr)); }
CHECK_EQ(0, pthread_join(thread_, nullptr));
}
// static // static
void* State::RunWrapper(void* arg) { void* State::RunWrapper(void* arg) {
...@@ -1121,17 +1107,16 @@ void RunMatchingBenchmarks(const std::string& spec, ...@@ -1121,17 +1107,16 @@ void RunMatchingBenchmarks(const std::string& spec,
for (const internal::Benchmark::Instance& benchmark : benchmarks) { for (const internal::Benchmark::Instance& benchmark : benchmarks) {
// Add width for _stddev and threads:XX // Add width for _stddev and threads:XX
if (benchmark.threads > 1 && FLAGS_benchmark_repetitions > 1) { if (benchmark.threads > 1 && FLAGS_benchmark_repetitions > 1) {
name_field_width = std::max<int>(name_field_width, name_field_width =
benchmark.name.size() + 17); std::max<int>(name_field_width, benchmark.name.size() + 17);
} else if (benchmark.threads> 1) { } else if (benchmark.threads > 1) {
name_field_width = std::max<int>(name_field_width, name_field_width =
benchmark.name.size() + 10); std::max<int>(name_field_width, benchmark.name.size() + 10);
} else if (FLAGS_benchmark_repetitions > 1) { } else if (FLAGS_benchmark_repetitions > 1) {
name_field_width = std::max<int>(name_field_width, name_field_width =
benchmark.name.size() + 7); std::max<int>(name_field_width, benchmark.name.size() + 7);
} else { } else {
name_field_width = std::max<int>(name_field_width, name_field_width = std::max<int>(name_field_width, benchmark.name.size());
benchmark.name.size());
} }
} }
...@@ -1139,7 +1124,7 @@ void RunMatchingBenchmarks(const std::string& spec, ...@@ -1139,7 +1124,7 @@ void RunMatchingBenchmarks(const std::string& spec,
BenchmarkContextData context; BenchmarkContextData context;
context.num_cpus = NumCPUs(); context.num_cpus = NumCPUs();
context.mhz_per_cpu = CyclesPerSecond() / 1000000.0f; context.mhz_per_cpu = CyclesPerSecond() / 1000000.0f;
// context.cpu_info = base::CompactCPUIDInfoString(); // context.cpu_info = base::CompactCPUIDInfoString();
context.cpu_scaling_enabled = CpuScalingEnabled(); context.cpu_scaling_enabled = CpuScalingEnabled();
context.name_field_width = name_field_width; context.name_field_width = name_field_width;
...@@ -1155,7 +1140,7 @@ void FindMatchingBenchmarkNames(const std::string& spec, ...@@ -1155,7 +1140,7 @@ void FindMatchingBenchmarkNames(const std::string& spec,
std::vector<internal::Benchmark::Instance> benchmarks; std::vector<internal::Benchmark::Instance> benchmarks;
internal::Benchmark::FindBenchmarks(spec, &benchmarks); internal::Benchmark::FindBenchmarks(spec, &benchmarks);
std::transform(benchmarks.begin(), benchmarks.end(), benchmark_names->begin(), std::transform(benchmarks.begin(), benchmarks.end(), benchmark_names->begin(),
[] (const internal::Benchmark::Instance& b) { return b.name; } ); [](const internal::Benchmark::Instance& b) { return b.name; });
} }
} // end namespace internal } // end namespace internal
...@@ -1172,7 +1157,6 @@ void RunSpecifiedBenchmarks() { ...@@ -1172,7 +1157,6 @@ void RunSpecifiedBenchmarks() {
} }
void Initialize(int* argc, const char** argv) { void Initialize(int* argc, const char** argv) {
//AtomicOps_Internalx86CPUFeaturesInit();
pthread_mutex_init(&benchmark_mutex, nullptr); pthread_mutex_init(&benchmark_mutex, nullptr);
pthread_mutex_init(&starting_mutex, nullptr); pthread_mutex_init(&starting_mutex, nullptr);
pthread_cond_init(&starting_cv, nullptr); pthread_cond_init(&starting_cv, nullptr);
......
...@@ -17,25 +17,40 @@ typedef const char* PlatformColorCode; ...@@ -17,25 +17,40 @@ typedef const char* PlatformColorCode;
PlatformColorCode GetPlatformColorCode(LogColor color) { PlatformColorCode GetPlatformColorCode(LogColor color) {
#ifdef OS_WINDOWS #ifdef OS_WINDOWS
switch (color) { switch (color) {
case COLOR_RED: return FOREGROUND_RED; case COLOR_RED:
case COLOR_GREEN: return FOREGROUND_GREEN; return FOREGROUND_RED;
case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; case COLOR_GREEN:
case COLOR_BLUE: return FOREGROUND_BLUE; return FOREGROUND_GREEN;
case COLOR_MAGENTA: return FOREGROUND_BLUE | FOREGROUND_RED; case COLOR_YELLOW:
case COLOR_CYAN: return FOREGROUND_BLUE | FOREGROUND_GREEN; return FOREGROUND_RED | FOREGROUND_GREEN;
case COLOR_BLUE:
return FOREGROUND_BLUE;
case COLOR_MAGENTA:
return FOREGROUND_BLUE | FOREGROUND_RED;
case COLOR_CYAN:
return FOREGROUND_BLUE | FOREGROUND_GREEN;
case COLOR_WHITE: // fall through to default case COLOR_WHITE: // fall through to default
default: return 0; default:
return 0;
} }
#else #else
switch (color) { switch (color) {
case COLOR_RED: return "1"; case COLOR_RED:
case COLOR_GREEN: return "2"; return "1";
case COLOR_YELLOW: return "3"; case COLOR_GREEN:
case COLOR_BLUE: return "4"; return "2";
case COLOR_MAGENTA: return "5"; case COLOR_YELLOW:
case COLOR_CYAN: return "6"; return "3";
case COLOR_WHITE: return "7"; case COLOR_BLUE:
default: return NULL; return "4";
case COLOR_MAGENTA:
return "5";
case COLOR_CYAN:
return "6";
case COLOR_WHITE:
return "7";
default:
return NULL;
}; };
#endif #endif
} }
...@@ -72,8 +87,7 @@ void ColorPrintf(LogColor color, const char* fmt, ...) { ...@@ -72,8 +87,7 @@ void ColorPrintf(LogColor color, const char* fmt, ...) {
SetConsoleTextAttribute(stdout_handle, old_color_attrs); SetConsoleTextAttribute(stdout_handle, old_color_attrs);
#else #else
const char* color_code = GetPlatformColorCode(color); const char* color_code = GetPlatformColorCode(color);
if (color_code) if (color_code) fprintf(stdout, "\033[0;3%sm", color_code);
fprintf(stdout, "\033[0;3%sm", color_code);
vprintf(fmt, args); vprintf(fmt, args);
printf("\033[m"); // Resets the terminal to default. printf("\033[m"); // Resets the terminal to default.
#endif #endif
......
...@@ -60,7 +60,6 @@ bool ParseDouble(const std::string& src_text, const char* str, double* value) { ...@@ -60,7 +60,6 @@ bool ParseDouble(const std::string& src_text, const char* str, double* value) {
return true; return true;
} }
inline const char* GetEnv(const char* name) { inline const char* GetEnv(const char* name) {
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
// We are on Windows CE, which has no environment variables. // We are on Windows CE, which has no environment variables.
...@@ -95,8 +94,7 @@ static std::string FlagToEnvVar(const char* flag) { ...@@ -95,8 +94,7 @@ static std::string FlagToEnvVar(const char* flag) {
bool BoolFromEnv(const char* flag, bool default_value) { bool BoolFromEnv(const char* flag, bool default_value) {
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = GetEnv(env_var.c_str()); const char* const string_value = GetEnv(env_var.c_str());
return string_value == NULL ? return string_value == NULL ? default_value : strcmp(string_value, "0") != 0;
default_value : strcmp(string_value, "0") != 0;
} }
// Reads and returns a 32-bit integer stored in the environment // Reads and returns a 32-bit integer stored in the environment
...@@ -111,8 +109,8 @@ int32_t Int32FromEnv(const char* flag, int32_t default_value) { ...@@ -111,8 +109,8 @@ int32_t Int32FromEnv(const char* flag, int32_t default_value) {
} }
int32_t result = default_value; int32_t result = default_value;
if (!ParseInt32(std::string("Environment variable ") + env_var, if (!ParseInt32(std::string("Environment variable ") + env_var, string_value,
string_value, &result)) { &result)) {
std::cout << "The default value " << default_value << " is used.\n"; std::cout << "The default value " << default_value << " is used.\n";
return default_value; return default_value;
} }
...@@ -133,8 +131,7 @@ const char* StringFromEnv(const char* flag, const char* default_value) { ...@@ -133,8 +131,7 @@ const char* StringFromEnv(const char* flag, const char* default_value) {
// part can be omitted. // part can be omitted.
// //
// Returns the value of the flag, or NULL if the parsing failed. // Returns the value of the flag, or NULL if the parsing failed.
const char* ParseFlagValue(const char* str, const char* ParseFlagValue(const char* str, const char* flag,
const char* flag,
bool def_optional) { bool def_optional) {
// str and flag must not be NULL. // str and flag must not be NULL.
if (str == NULL || flag == NULL) return NULL; if (str == NULL || flag == NULL) return NULL;
...@@ -148,8 +145,7 @@ const char* ParseFlagValue(const char* str, ...@@ -148,8 +145,7 @@ const char* ParseFlagValue(const char* str,
const char* flag_end = str + flag_len; const char* flag_end = str + flag_len;
// When def_optional is true, it's OK to not have a "=value" part. // When def_optional is true, it's OK to not have a "=value" part.
if (def_optional && (flag_end[0] == '\0')) if (def_optional && (flag_end[0] == '\0')) return flag_end;
return flag_end;
// If def_optional is true and there are more characters after the // If def_optional is true and there are more characters after the
// flag name, or if def_optional is false, there must be a '=' after // flag name, or if def_optional is false, there must be a '=' after
...@@ -180,8 +176,8 @@ bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { ...@@ -180,8 +176,8 @@ bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) {
if (value_str == NULL) return false; if (value_str == NULL) return false;
// Sets *value to the value of the flag. // Sets *value to the value of the flag.
return ParseInt32(std::string("The value of flag --") + flag, return ParseInt32(std::string("The value of flag --") + flag, value_str,
value_str, value); value);
} }
bool ParseDoubleFlag(const char* str, const char* flag, double* value) { bool ParseDoubleFlag(const char* str, const char* flag, double* value) {
...@@ -192,8 +188,8 @@ bool ParseDoubleFlag(const char* str, const char* flag, double* value) { ...@@ -192,8 +188,8 @@ bool ParseDoubleFlag(const char* str, const char* flag, double* value) {
if (value_str == NULL) return false; if (value_str == NULL) return false;
// Sets *value to the value of the flag. // Sets *value to the value of the flag.
return ParseDouble(std::string("The value of flag --") + flag, return ParseDouble(std::string("The value of flag --") + flag, value_str,
value_str, value); value);
} }
bool ParseStringFlag(const char* str, const char* flag, std::string* value) { bool ParseStringFlag(const char* str, const char* flag, std::string* value) {
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <stdint.h> #include <stdint.h>
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
# include <mach/mach_time.h> #include <mach/mach_time.h>
#endif #endif
// For MSVC, we want to use '_asm rdtsc' when possible (since it works // For MSVC, we want to use '_asm rdtsc' when possible (since it works
// with even ancient MSVC compilers), and when not possible the // with even ancient MSVC compilers), and when not possible the
...@@ -48,8 +48,8 @@ namespace benchmark { ...@@ -48,8 +48,8 @@ namespace benchmark {
// with modifications by m3b. See also // with modifications by m3b. See also
// https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h // https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h
namespace cycleclock { namespace cycleclock {
// This should return the number of cycles since power-on. Thread-safe. // This should return the number of cycles since power-on. Thread-safe.
inline ATTRIBUTE_ALWAYS_INLINE int64_t Now() { inline ATTRIBUTE_ALWAYS_INLINE int64_t Now() {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
// this goes at the top because we need ALL Macs, regardless of // this goes at the top because we need ALL Macs, regardless of
// architecture, to return the number of "mach time units" that // architecture, to return the number of "mach time units" that
...@@ -63,29 +63,29 @@ namespace cycleclock { ...@@ -63,29 +63,29 @@ namespace cycleclock {
return mach_absolute_time(); return mach_absolute_time();
#elif defined(__i386__) #elif defined(__i386__)
int64_t ret; int64_t ret;
__asm__ volatile ("rdtsc" : "=A" (ret) ); __asm__ volatile("rdtsc" : "=A"(ret));
return ret; return ret;
#elif defined(__x86_64__) || defined(__amd64__) #elif defined(__x86_64__) || defined(__amd64__)
uint64_t low, high; uint64_t low, high;
__asm__ volatile ("rdtsc" : "=a" (low), "=d" (high)); __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
return (high << 32) | low; return (high << 32) | low;
#elif defined(__powerpc__) || defined(__ppc__) #elif defined(__powerpc__) || defined(__ppc__)
// This returns a time-base, which is not always precisely a cycle-count. // This returns a time-base, which is not always precisely a cycle-count.
int64_t tbl, tbu0, tbu1; int64_t tbl, tbu0, tbu1;
asm("mftbu %0" : "=r" (tbu0)); asm("mftbu %0" : "=r"(tbu0));
asm("mftb %0" : "=r" (tbl)); asm("mftb %0" : "=r"(tbl));
asm("mftbu %0" : "=r" (tbu1)); asm("mftbu %0" : "=r"(tbu1));
tbl &= -static_cast<int64>(tbu0 == tbu1); tbl &= -static_cast<int64>(tbu0 == tbu1);
// high 32 bits in tbu1; low 32 bits in tbl (tbu0 is garbage) // high 32 bits in tbu1; low 32 bits in tbl (tbu0 is garbage)
return (tbu1 << 32) | tbl; return (tbu1 << 32) | tbl;
#elif defined(__sparc__) #elif defined(__sparc__)
int64_t tick; int64_t tick;
asm(".byte 0x83, 0x41, 0x00, 0x00"); asm(".byte 0x83, 0x41, 0x00, 0x00");
asm("mov %%g1, %0" : "=r" (tick)); asm("mov %%g1, %0" : "=r"(tick));
return tick; return tick;
#elif defined(__ia64__) #elif defined(__ia64__)
int64_t itc; int64_t itc;
asm("mov %0 = ar.itc" : "=r" (itc)); asm("mov %0 = ar.itc" : "=r"(itc));
return itc; return itc;
#elif defined(COMPILER_MSVC) && defined(_M_IX86) #elif defined(COMPILER_MSVC) && defined(_M_IX86)
// Older MSVC compilers (like 7.x) don't seem to support the // Older MSVC compilers (like 7.x) don't seem to support the
...@@ -101,11 +101,11 @@ namespace cycleclock { ...@@ -101,11 +101,11 @@ namespace cycleclock {
uint32_t pmuseren; uint32_t pmuseren;
uint32_t pmcntenset; uint32_t pmcntenset;
// Read the user mode perf monitor counter access permissions. // Read the user mode perf monitor counter access permissions.
asm("mrc p15, 0, %0, c9, c14, 0" : "=r" (pmuseren)); asm("mrc p15, 0, %0, c9, c14, 0" : "=r"(pmuseren));
if (pmuseren & 1) { // Allows reading perfmon counters for user mode code. if (pmuseren & 1) { // Allows reading perfmon counters for user mode code.
asm("mrc p15, 0, %0, c9, c12, 1" : "=r" (pmcntenset)); asm("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcntenset));
if (pmcntenset & 0x80000000ul) { // Is it counting? if (pmcntenset & 0x80000000ul) { // Is it counting?
asm("mrc p15, 0, %0, c9, c13, 0" : "=r" (pmccntr)); asm("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr));
// The counter is set up to count every 64th cycle // The counter is set up to count every 64th cycle
return static_cast<int64>(pmccntr) * 64; // Should optimize to << 6 return static_cast<int64>(pmccntr) * 64; // Should optimize to << 6
} }
...@@ -126,7 +126,7 @@ namespace cycleclock { ...@@ -126,7 +126,7 @@ namespace cycleclock {
// a fast implementation and use generic version if nothing better is available. // a fast implementation and use generic version if nothing better is available.
#error You need to define CycleTimer for your OS and CPU #error You need to define CycleTimer for your OS and CPU
#endif #endif
} }
} // end namespace cycleclock } // end namespace cycleclock
} // end namespace benchmark } // end namespace benchmark
......
...@@ -10,9 +10,7 @@ class mutex_lock { ...@@ -10,9 +10,7 @@ class mutex_lock {
pthread_mutex_lock(mu_); pthread_mutex_lock(mu_);
} }
~mutex_lock() { ~mutex_lock() { pthread_mutex_unlock(mu_); }
pthread_mutex_unlock(mu_);
}
private: private:
pthread_mutex_t* mu_; pthread_mutex_t* mu_;
......
...@@ -6,9 +6,7 @@ ...@@ -6,9 +6,7 @@
namespace benchmark { namespace benchmark {
#ifdef OS_WINDOWS #ifdef OS_WINDOWS
// Window's _sleep takes milliseconds argument. // Window's _sleep takes milliseconds argument.
void SleepForMilliseconds(int milliseconds) { void SleepForMilliseconds(int milliseconds) { _sleep(milliseconds); }
_sleep(milliseconds);
}
void SleepForSeconds(double seconds) { void SleepForSeconds(double seconds) {
SleepForMilliseconds(static_cast<int>(kNumMillisPerSecond * seconds)); SleepForMilliseconds(static_cast<int>(kNumMillisPerSecond * seconds));
} }
......
...@@ -17,22 +17,19 @@ typedef Stat1<double, double> Stat1_d; ...@@ -17,22 +17,19 @@ typedef Stat1<double, double> Stat1_d;
typedef Stat1MinMax<float, float> Stat1MinMax_f; typedef Stat1MinMax<float, float> Stat1MinMax_f;
typedef Stat1MinMax<double, double> Stat1MinMax_d; typedef Stat1MinMax<double, double> Stat1MinMax_d;
template <typename VType> class Vector2; template <typename VType>
template <typename VType> class Vector3; class Vector2;
template <typename VType> class Vector4; template <typename VType>
class Vector3;
template <typename VType>
class Vector4;
template <typename VType, typename NumType> template <typename VType, typename NumType>
class Stat1 { class Stat1 {
public: public:
typedef Stat1<VType, NumType> Self; typedef Stat1<VType, NumType> Self;
Stat1() { Stat1() { Clear(); }
Clear();
}
void Clear() {
numsamples_ = NumType();
sum_squares_ = sum_ = VType();
}
// Create a sample of value dat and weight 1 // Create a sample of value dat and weight 1
explicit Stat1(const VType &dat) { explicit Stat1(const VType &dat) {
sum_ = dat; sum_ = dat;
...@@ -43,7 +40,7 @@ class Stat1 { ...@@ -43,7 +40,7 @@ class Stat1 {
// and end(excluded) // and end(excluded)
explicit Stat1(const VType *begin, const VType *end) { explicit Stat1(const VType *begin, const VType *end) {
Clear(); Clear();
for ( const VType *item = begin; item < end; ++item ) { for (const VType *item = begin; item < end; ++item) {
(*this) += Stat1(*item); (*this) += Stat1(*item);
} }
} }
...@@ -60,58 +57,60 @@ class Stat1 { ...@@ -60,58 +57,60 @@ class Stat1 {
numsamples_ = stat.numsamples_; numsamples_ = stat.numsamples_;
} }
inline Self &operator =(const Self &stat) { void Clear() {
numsamples_ = NumType();
sum_squares_ = sum_ = VType();
}
Self& operator=(const Self &stat) {
sum_ = stat.sum_; sum_ = stat.sum_;
sum_squares_ = stat.sum_squares_; sum_squares_ = stat.sum_squares_;
numsamples_ = stat.numsamples_; numsamples_ = stat.numsamples_;
return (*this); return (*this);
} }
// Merge statistics from two sample sets. // Merge statistics from two sample sets.
inline Self &operator +=(const Self &stat) { Self& operator+=(const Self &stat) {
sum_ += stat.sum_; sum_ += stat.sum_;
sum_squares_+= stat.sum_squares_; sum_squares_ += stat.sum_squares_;
numsamples_ += stat.numsamples_; numsamples_ += stat.numsamples_;
return (*this); return (*this);
} }
// The operation opposite to += // The operation opposite to +=
inline Self &operator -=(const Self &stat) { Self& operator-=(const Self &stat) {
sum_ -= stat.sum_; sum_ -= stat.sum_;
sum_squares_-= stat.sum_squares_; sum_squares_ -= stat.sum_squares_;
numsamples_ -= stat.numsamples_; numsamples_ -= stat.numsamples_;
return (*this); return (*this);
} }
// Multiply the weight of the set of samples by a factor k // Multiply the weight of the set of samples by a factor k
inline Self &operator *=(const VType &k) { Self& operator*=(const VType &k) {
sum_ *= k; sum_ *= k;
sum_squares_*= k; sum_squares_ *= k;
numsamples_ *= k; numsamples_ *= k;
return (*this); return (*this);
} }
// Merge statistics from two sample sets. // Merge statistics from two sample sets.
inline Self operator + (const Self &stat) const { Self operator+(const Self& stat) const { return Self(*this) += stat; }
return Self(*this) += stat;
}
// The operation opposite to + // The operation opposite to +
inline Self operator - (const Self &stat) const { Self operator-(const Self& stat) const { return Self(*this) -= stat; }
return Self(*this) -= stat;
}
// Multiply the weight of the set of samples by a factor k // Multiply the weight of the set of samples by a factor k
inline Self operator * (const VType &k) const { Self operator*(const VType& k) const { return Self(*this) *= k; }
return Self(*this) *= k;
}
// Return the total weight of this sample set // Return the total weight of this sample set
NumType NumSamples() const { NumType numSamples() const { return numsamples_; }
return numsamples_;
}
// Return the sum of this sample set // Return the sum of this sample set
VType Sum() const { VType sum() const { return sum_; }
return sum_;
}
// Return the mean of this sample set // Return the mean of this sample set
VType Mean() const { VType Mean() const {
if (numsamples_ == 0) return VType(); if (numsamples_ == 0) return VType();
return sum_ * (1.0 / numsamples_); return sum_ * (1.0 / numsamples_);
} }
// Return the mean of this sample set and compute the standard deviation at // Return the mean of this sample set and compute the standard deviation at
// the same time. // the same time.
VType Mean(VType *stddev) const { VType Mean(VType *stddev) const {
...@@ -123,6 +122,7 @@ class Stat1 { ...@@ -123,6 +122,7 @@ class Stat1 {
} }
return mean; return mean;
} }
// Return the standard deviation of the sample set // Return the standard deviation of the sample set
VType StdDev() const { VType StdDev() const {
if (numsamples_ == 0) return VType(); if (numsamples_ == 0) return VType();
...@@ -130,6 +130,7 @@ class Stat1 { ...@@ -130,6 +130,7 @@ class Stat1 {
VType avg_squares = sum_squares_ * (1.0 / numsamples_); VType avg_squares = sum_squares_ * (1.0 / numsamples_);
return Sqrt(avg_squares - Sqr(mean)); return Sqrt(avg_squares - Sqr(mean));
} }
private: private:
// Let i be the index of the samples provided (using +=) // Let i be the index of the samples provided (using +=)
// and weight[i],value[i] be the data of sample #i // and weight[i],value[i] be the data of sample #i
...@@ -141,17 +142,18 @@ class Stat1 { ...@@ -141,17 +142,18 @@ class Stat1 {
// Template function used to square a number. // Template function used to square a number.
// For a vector we square all components // For a vector we square all components
template <typename SType> template <typename SType>
static inline SType Sqr(const SType &dat) { static inline SType Sqr(const SType &dat) { return dat * dat; }
return dat * dat;
}
template <typename SType> template <typename SType>
static inline Vector2<SType> Sqr(const Vector2<SType> &dat) { static inline Vector2<SType> Sqr(const Vector2<SType> &dat) {
return dat.MulComponents(dat); return dat.MulComponents(dat);
} }
template <typename SType> template <typename SType>
static inline Vector3<SType> Sqr(const Vector3<SType> &dat) { static inline Vector3<SType> Sqr(const Vector3<SType> &dat) {
return dat.MulComponents(dat); return dat.MulComponents(dat);
} }
template <typename SType> template <typename SType>
static inline Vector4<SType> Sqr(const Vector4<SType> &dat) { static inline Vector4<SType> Sqr(const Vector4<SType> &dat) {
return dat.MulComponents(dat); return dat.MulComponents(dat);
...@@ -162,20 +164,22 @@ class Stat1 { ...@@ -162,20 +164,22 @@ class Stat1 {
template <typename SType> template <typename SType>
static inline SType Sqrt(const SType &dat) { static inline SType Sqrt(const SType &dat) {
// Avoid NaN due to imprecision in the calculations // Avoid NaN due to imprecision in the calculations
if ( dat < 0 ) if (dat < 0) return 0;
return 0;
return sqrt(dat); return sqrt(dat);
} }
template <typename SType> template <typename SType>
static inline Vector2<SType> Sqrt(const Vector2<SType> &dat) { static inline Vector2<SType> Sqrt(const Vector2<SType> &dat) {
// Avoid NaN due to imprecision in the calculations // Avoid NaN due to imprecision in the calculations
return Max(dat, Vector2<SType>()).Sqrt(); return Max(dat, Vector2<SType>()).Sqrt();
} }
template <typename SType> template <typename SType>
static inline Vector3<SType> Sqrt(const Vector3<SType> &dat) { static inline Vector3<SType> Sqrt(const Vector3<SType> &dat) {
// Avoid NaN due to imprecision in the calculations // Avoid NaN due to imprecision in the calculations
return Max(dat, Vector3<SType>()).Sqrt(); return Max(dat, Vector3<SType>()).Sqrt();
} }
template <typename SType> template <typename SType>
static inline Vector4<SType> Sqrt(const Vector4<SType> &dat) { static inline Vector4<SType> Sqrt(const Vector4<SType> &dat) {
// Avoid NaN due to imprecision in the calculations // Avoid NaN due to imprecision in the calculations
...@@ -185,15 +189,12 @@ class Stat1 { ...@@ -185,15 +189,12 @@ class Stat1 {
// Useful printing function // Useful printing function
template <typename VType, typename NumType> template <typename VType, typename NumType>
inline std::ostream& operator<<(std::ostream& out, std::ostream& operator<<(std::ostream& out, const Stat1<VType, NumType>& s) {
const Stat1<VType, NumType>& s) { out << "{ avg = " << s.Mean() << " std = " << s.StdDev()
out << "{ avg = " << s.Mean()
<< " std = " << s.StdDev()
<< " nsamples = " << s.NumSamples() << "}"; << " nsamples = " << s.NumSamples() << "}";
return out; return out;
} }
// Stat1MinMax: same as Stat1, but it also // Stat1MinMax: same as Stat1, but it also
// keeps the Min and Max values; the "-" // keeps the Min and Max values; the "-"
// operator is disabled because it cannot be implemented // operator is disabled because it cannot be implemented
...@@ -203,19 +204,7 @@ class Stat1MinMax : public Stat1<VType, NumType> { ...@@ -203,19 +204,7 @@ class Stat1MinMax : public Stat1<VType, NumType> {
public: public:
typedef Stat1MinMax<VType, NumType> Self; typedef Stat1MinMax<VType, NumType> Self;
Stat1MinMax() { Stat1MinMax() { Clear(); }
Clear();
}
void Clear() {
Stat1<VType, NumType>::Clear();
if (std::numeric_limits<VType>::has_infinity) {
min_ = std::numeric_limits<VType>::infinity();
max_ = -std::numeric_limits<VType>::infinity();
} else {
min_ = std::numeric_limits<VType>::max();
max_ = std::numeric_limits<VType>::min();
}
}
// Create a sample of value dat and weight 1 // Create a sample of value dat and weight 1
explicit Stat1MinMax(const VType &dat) : Stat1<VType, NumType>(dat) { explicit Stat1MinMax(const VType &dat) : Stat1<VType, NumType>(dat) {
max_ = dat; max_ = dat;
...@@ -225,7 +214,7 @@ class Stat1MinMax : public Stat1<VType, NumType> { ...@@ -225,7 +214,7 @@ class Stat1MinMax : public Stat1<VType, NumType> {
// and end(excluded) // and end(excluded)
explicit Stat1MinMax(const VType *begin, const VType *end) { explicit Stat1MinMax(const VType *begin, const VType *end) {
Clear(); Clear();
for ( const VType *item = begin; item < end; ++item ) { for (const VType* item = begin; item < end; ++item) {
(*this) += Stat1MinMax(*item); (*this) += Stat1MinMax(*item);
} }
} }
...@@ -240,51 +229,55 @@ class Stat1MinMax : public Stat1<VType, NumType> { ...@@ -240,51 +229,55 @@ class Stat1MinMax : public Stat1<VType, NumType> {
max_ = stat.max_; max_ = stat.max_;
min_ = stat.min_; min_ = stat.min_;
} }
inline Self &operator =(const Self &stat) {
void Clear() {
Stat1<VType, NumType>::Clear();
if (std::numeric_limits<VType>::has_infinity) {
min_ = std::numeric_limits<VType>::infinity();
max_ = -std::numeric_limits<VType>::infinity();
} else {
min_ = std::numeric_limits<VType>::max();
max_ = std::numeric_limits<VType>::min();
}
}
Self& operator=(const Self& stat) {
this->Stat1<VType, NumType>::operator=(stat); this->Stat1<VType, NumType>::operator=(stat);
max_ = stat.max_; max_ = stat.max_;
min_ = stat.min_; min_ = stat.min_;
return (*this); return (*this);
} }
// Merge statistics from two sample sets. // Merge statistics from two sample sets.
inline Self &operator +=(const Self &stat) { Self& operator+=(const Self& stat) {
this->Stat1<VType, NumType>::operator+=(stat); this->Stat1<VType, NumType>::operator+=(stat);
if (stat.max_ > max_) max_ = stat.max_; if (stat.max_ > max_) max_ = stat.max_;
if (stat.min_ < min_) min_ = stat.min_; if (stat.min_ < min_) min_ = stat.min_;
return (*this); return (*this);
} }
// Multiply the weight of the set of samples by a factor k // Multiply the weight of the set of samples by a factor k
inline Self &operator *=(const VType &stat) { Self& operator*=(const VType& stat) {
this->Stat1<VType, NumType>::operator*=(stat); this->Stat1<VType, NumType>::operator*=(stat);
return (*this); return (*this);
} }
// Merge statistics from two sample sets. // Merge statistics from two sample sets.
inline Self operator + (const Self &stat) const { Self operator+(const Self& stat) const { return Self(*this) += stat; }
return Self(*this) += stat;
}
// Multiply the weight of the set of samples by a factor k // Multiply the weight of the set of samples by a factor k
inline Self operator * (const VType &k) const { Self operator*(const VType& k) const { return Self(*this) *= k; }
return Self(*this) *= k;
} // Return the maximal value in this sample set
VType max() const { return max_; }
// Return the minimal value in this sample set
VType min() const { return min_; }
private: private:
// The - operation makes no sense with Min/Max // The - operation makes no sense with Min/Max
// unless we keep the full list of values (but we don't) // unless we keep the full list of values (but we don't)
// make it private, and let it undefined so nobody can call it // make it private, and let it undefined so nobody can call it
Self &operator -=(const Self &stat); // senseless. let it undefined. Self &operator-=(const Self& stat); // senseless. let it undefined.
// The operation opposite to - // The operation opposite to -
Self operator - (const Self &stat) const; // senseless. let it undefined. Self operator-(const Self& stat) const; // senseless. let it undefined.
public:
// Return the maximal value in this sample set
VType Max() const {
return max_;
}
// Return the minimal value in this sample set
VType Min() const {
return min_;
}
private:
// Let i be the index of the samples provided (using +=) // Let i be the index of the samples provided (using +=)
// and weight[i],value[i] be the data of sample #i // and weight[i],value[i] be the data of sample #i
// then the variables have the following meaning: // then the variables have the following meaning:
...@@ -294,12 +287,10 @@ class Stat1MinMax : public Stat1<VType, NumType> { ...@@ -294,12 +287,10 @@ class Stat1MinMax : public Stat1<VType, NumType> {
// Useful printing function // Useful printing function
template <typename VType, typename NumType> template <typename VType, typename NumType>
inline std::ostream& operator <<(std::ostream& out, std::ostream& operator<<(std::ostream& out,
const Stat1MinMax<VType, NumType>& s) { const Stat1MinMax<VType, NumType>& s) {
out << "{ avg = " << s.Mean() out << "{ avg = " << s.Mean() << " std = " << s.StdDev()
<< " std = " << s.StdDev() << " nsamples = " << s.NumSamples() << " min = " << s.Min()
<< " nsamples = " << s.NumSamples()
<< " min = " << s.Min()
<< " max = " << s.Max() << "}"; << " max = " << s.Max() << "}";
return out; return out;
} }
......
...@@ -39,7 +39,7 @@ int64_t EstimateCyclesPerSecond(const int estimate_time_ms) { ...@@ -39,7 +39,7 @@ int64_t EstimateCyclesPerSecond(const int estimate_time_ms) {
// Helper function for reading an int from a file. Returns true if successful // Helper function for reading an int from a file. Returns true if successful
// and the memory location pointed to by value is set to the value read. // and the memory location pointed to by value is set to the value read.
bool ReadIntFromFile(const char *file, int *value) { bool ReadIntFromFile(const char* file, int* value) {
bool ret = false; bool ret = false;
int fd = open(file, O_RDONLY); int fd = open(file, O_RDONLY);
if (fd != -1) { if (fd != -1) {
...@@ -116,42 +116,41 @@ void InitializeSystemInfo() { ...@@ -116,42 +116,41 @@ void InitializeSystemInfo() {
if (sizeof(line) == oldlinelen + 1) // oldlinelen took up entire line if (sizeof(line) == oldlinelen + 1) // oldlinelen took up entire line
line[0] = '\0'; line[0] = '\0';
else // still other lines left to save else // still other lines left to save
memmove(line, line + oldlinelen+1, sizeof(line) - (oldlinelen+1)); memmove(line, line + oldlinelen + 1, sizeof(line) - (oldlinelen + 1));
// Terminate the new line, reading more if we can't find the newline // Terminate the new line, reading more if we can't find the newline
char* newline = strchr(line, '\n'); char* newline = strchr(line, '\n');
if (newline == NULL) { if (newline == NULL) {
const int linelen = strlen(line); const int linelen = strlen(line);
const int bytes_to_read = sizeof(line)-1 - linelen; const int bytes_to_read = sizeof(line) - 1 - linelen;
CHECK(bytes_to_read > 0); // because the memmove recovered >=1 bytes CHECK(bytes_to_read > 0); // because the memmove recovered >=1 bytes
chars_read = read(fd, line + linelen, bytes_to_read); chars_read = read(fd, line + linelen, bytes_to_read);
line[linelen + chars_read] = '\0'; line[linelen + chars_read] = '\0';
newline = strchr(line, '\n'); newline = strchr(line, '\n');
} }
if (newline != NULL) if (newline != NULL) *newline = '\0';
*newline = '\0';
// When parsing the "cpu MHz" and "bogomips" (fallback) entries, we only // When parsing the "cpu MHz" and "bogomips" (fallback) entries, we only
// accept postive values. Some environments (virtual machines) report zero, // accept postive values. Some environments (virtual machines) report zero,
// which would cause infinite looping in WallTime_Init. // which would cause infinite looping in WallTime_Init.
if (!saw_mhz && strncasecmp(line, "cpu MHz", sizeof("cpu MHz")-1) == 0) { if (!saw_mhz && strncasecmp(line, "cpu MHz", sizeof("cpu MHz") - 1) == 0) {
const char* freqstr = strchr(line, ':'); const char* freqstr = strchr(line, ':');
if (freqstr) { if (freqstr) {
cpuinfo_cycles_per_second = strtod(freqstr+1, &err) * 1000000.0; cpuinfo_cycles_per_second = strtod(freqstr + 1, &err) * 1000000.0;
if (freqstr[1] != '\0' && *err == '\0' && cpuinfo_cycles_per_second > 0) if (freqstr[1] != '\0' && *err == '\0' && cpuinfo_cycles_per_second > 0)
saw_mhz = true; saw_mhz = true;
} }
} else if (strncasecmp(line, "bogomips", sizeof("bogomips")-1) == 0) { } else if (strncasecmp(line, "bogomips", sizeof("bogomips") - 1) == 0) {
const char* freqstr = strchr(line, ':'); const char* freqstr = strchr(line, ':');
if (freqstr) { if (freqstr) {
bogo_clock = strtod(freqstr+1, &err) * 1000000.0; bogo_clock = strtod(freqstr + 1, &err) * 1000000.0;
if (freqstr[1] != '\0' && *err == '\0' && bogo_clock > 0) if (freqstr[1] != '\0' && *err == '\0' && bogo_clock > 0)
saw_bogo = true; saw_bogo = true;
} }
} else if (strncasecmp(line, "processor", sizeof("processor")-1) == 0) { } else if (strncasecmp(line, "processor", sizeof("processor") - 1) == 0) {
num_cpus++; // count up every time we see an "processor :" entry num_cpus++; // count up every time we see an "processor :" entry
const char* freqstr = strchr(line, ':'); const char* freqstr = strchr(line, ':');
if (freqstr) { if (freqstr) {
const int cpu_id = strtol(freqstr+1, &err, 10); const int cpu_id = strtol(freqstr + 1, &err, 10);
if (freqstr[1] != '\0' && *err == '\0' && max_cpu_id < cpu_id) if (freqstr[1] != '\0' && *err == '\0' && max_cpu_id < cpu_id)
max_cpu_id = cpu_id; max_cpu_id = cpu_id;
} }
...@@ -181,17 +180,17 @@ void InitializeSystemInfo() { ...@@ -181,17 +180,17 @@ void InitializeSystemInfo() {
} }
#elif defined OS_FREEBSD #elif defined OS_FREEBSD
// For this sysctl to work, the machine must be configured without // For this sysctl to work, the machine must be configured without
// SMP, APIC, or APM support. hz should be 64-bit in freebsd 7.0 // SMP, APIC, or APM support. hz should be 64-bit in freebsd 7.0
// and later. Before that, it's a 32-bit quantity (and gives the // and later. Before that, it's a 32-bit quantity (and gives the
// wrong answer on machines faster than 2^32 Hz). See // wrong answer on machines faster than 2^32 Hz). See
// http://lists.freebsd.org/pipermail/freebsd-i386/2004-November/001846.html // http://lists.freebsd.org/pipermail/freebsd-i386/2004-November/001846.html
// But also compare FreeBSD 7.0: // But also compare FreeBSD 7.0:
// http://fxr.watson.org/fxr/source/i386/i386/tsc.c?v=RELENG70#L223 // http://fxr.watson.org/fxr/source/i386/i386/tsc.c?v=RELENG70#L223
// 231 error = sysctl_handle_quad(oidp, &freq, 0, req); // 231 error = sysctl_handle_quad(oidp, &freq, 0, req);
// To FreeBSD 6.3 (it's the same in 6-STABLE): // To FreeBSD 6.3 (it's the same in 6-STABLE):
// http://fxr.watson.org/fxr/source/i386/i386/tsc.c?v=RELENG6#L131 // http://fxr.watson.org/fxr/source/i386/i386/tsc.c?v=RELENG6#L131
// 139 error = sysctl_handle_int(oidp, &freq, sizeof(freq), req); // 139 error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
#if __FreeBSD__ >= 7 #if __FreeBSD__ >= 7
uint64_t hz = 0; uint64_t hz = 0;
#else #else
...@@ -199,25 +198,25 @@ void InitializeSystemInfo() { ...@@ -199,25 +198,25 @@ void InitializeSystemInfo() {
#endif #endif
size_t sz = sizeof(hz); size_t sz = sizeof(hz);
const char *sysctl_path = "machdep.tsc_freq"; const char *sysctl_path = "machdep.tsc_freq";
if ( sysctlbyname(sysctl_path, &hz, &sz, NULL, 0) != 0 ) { if (sysctlbyname(sysctl_path, &hz, &sz, NULL, 0) != 0) {
fprintf(stderr, "Unable to determine clock rate from sysctl: %s: %s\n", fprintf(stderr, "Unable to determine clock rate from sysctl: %s: %s\n",
sysctl_path, strerror(errno)); sysctl_path, strerror(errno));
cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000); cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000);
} else { } else {
cpuinfo_cycles_per_second = hz; cpuinfo_cycles_per_second = hz;
} }
// TODO: also figure out cpuinfo_num_cpus // TODO: also figure out cpuinfo_num_cpus
#elif defined OS_WINDOWS #elif defined OS_WINDOWS
# pragma comment(lib, "shlwapi.lib") // for SHGetValue() #pragma comment(lib, "shlwapi.lib") // for SHGetValue()
// In NT, read MHz from the registry. If we fail to do so or we're in win9x // In NT, read MHz from the registry. If we fail to do so or we're in win9x
// then make a crude estimate. // then make a crude estimate.
OSVERSIONINFO os; OSVERSIONINFO os;
os.dwOSVersionInfoSize = sizeof(os); os.dwOSVersionInfoSize = sizeof(os);
DWORD data, data_size = sizeof(data); DWORD data, data_size = sizeof(data);
if (GetVersionEx(&os) && if (GetVersionEx(&os) && os.dwPlatformId == VER_PLATFORM_WIN32_NT &&
os.dwPlatformId == VER_PLATFORM_WIN32_NT && SUCCEEDED(
SUCCEEDED(SHGetValueA(HKEY_LOCAL_MACHINE, SHGetValueA(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
"~MHz", NULL, &data, &data_size))) "~MHz", NULL, &data, &data_size)))
cpuinfo_cycles_per_second = (int64)data * (int64)(1000 * 1000); // was mhz cpuinfo_cycles_per_second = (int64)data * (int64)(1000 * 1000); // was mhz
...@@ -243,10 +242,10 @@ void InitializeSystemInfo() { ...@@ -243,10 +242,10 @@ void InitializeSystemInfo() {
int num_cpus = 0; int num_cpus = 0;
size_t size = sizeof(num_cpus); size_t size = sizeof(num_cpus);
int numcpus_name[] = { CTL_HW, HW_NCPU }; int numcpus_name[] = {CTL_HW, HW_NCPU};
if (::sysctl(numcpus_name, arraysize(numcpus_name), &num_cpus, &size, 0, 0) if (::sysctl(numcpus_name, arraysize(numcpus_name), &num_cpus, &size, 0, 0) ==
== 0 0 &&
&& (size == sizeof(num_cpus))) (size == sizeof(num_cpus)))
cpuinfo_num_cpus = num_cpus; cpuinfo_num_cpus = num_cpus;
#else #else
...@@ -262,15 +261,15 @@ static double MyCPUUsageRUsage() { ...@@ -262,15 +261,15 @@ static double MyCPUUsageRUsage() {
struct rusage ru; struct rusage ru;
if (getrusage(RUSAGE_SELF, &ru) == 0) { if (getrusage(RUSAGE_SELF, &ru) == 0) {
return (static_cast<double>(ru.ru_utime.tv_sec) + return (static_cast<double>(ru.ru_utime.tv_sec) +
static_cast<double>(ru.ru_utime.tv_usec)*1e-6 + static_cast<double>(ru.ru_utime.tv_usec) * 1e-6 +
static_cast<double>(ru.ru_stime.tv_sec) + static_cast<double>(ru.ru_stime.tv_sec) +
static_cast<double>(ru.ru_stime.tv_usec)*1e-6); static_cast<double>(ru.ru_stime.tv_usec) * 1e-6);
} else { } else {
return 0.0; return 0.0;
} }
} }
static bool MyCPUUsageCPUTimeNsLocked(double *cputime) { static bool MyCPUUsageCPUTimeNsLocked(double* cputime) {
static int cputime_fd = -1; static int cputime_fd = -1;
if (cputime_fd == -1) { if (cputime_fd == -1) {
cputime_fd = open("/proc/self/cputime_ns", O_RDONLY); cputime_fd = open("/proc/self/cputime_ns", O_RDONLY);
...@@ -281,7 +280,7 @@ static bool MyCPUUsageCPUTimeNsLocked(double *cputime) { ...@@ -281,7 +280,7 @@ static bool MyCPUUsageCPUTimeNsLocked(double *cputime) {
} }
char buff[64]; char buff[64];
memset(buff, 0, sizeof(buff)); memset(buff, 0, sizeof(buff));
if (pread(cputime_fd, buff, sizeof(buff)-1, 0) <= 0) { if (pread(cputime_fd, buff, sizeof(buff) - 1, 0) <= 0) {
close(cputime_fd); close(cputime_fd);
cputime_fd = -1; cputime_fd = -1;
return false; return false;
...@@ -317,9 +316,9 @@ double ChildrenCPUUsage() { ...@@ -317,9 +316,9 @@ double ChildrenCPUUsage() {
struct rusage ru; struct rusage ru;
if (getrusage(RUSAGE_CHILDREN, &ru) == 0) { if (getrusage(RUSAGE_CHILDREN, &ru) == 0) {
return (static_cast<double>(ru.ru_utime.tv_sec) + return (static_cast<double>(ru.ru_utime.tv_sec) +
static_cast<double>(ru.ru_utime.tv_usec)*1e-6 + static_cast<double>(ru.ru_utime.tv_usec) * 1e-6 +
static_cast<double>(ru.ru_stime.tv_sec) + static_cast<double>(ru.ru_stime.tv_sec) +
static_cast<double>(ru.ru_stime.tv_usec)*1e-6); static_cast<double>(ru.ru_stime.tv_usec) * 1e-6);
} else { } else {
return 0.0; return 0.0;
} }
......
...@@ -75,8 +75,8 @@ void Initialize() { ...@@ -75,8 +75,8 @@ void Initialize() {
cycles_per_second = static_cast<int64_t>(CyclesPerSecond()); cycles_per_second = static_cast<int64_t>(CyclesPerSecond());
CHECK(cycles_per_second != 0); CHECK(cycles_per_second != 0);
seconds_per_cycle = 1.0 / cycles_per_second; seconds_per_cycle = 1.0 / cycles_per_second;
max_interval_cycles = static_cast<int64_t>( max_interval_cycles =
cycles_per_second * kMaxErrorInterval); static_cast<int64_t>(cycles_per_second * kMaxErrorInterval);
do { do {
base_cycletime = cycleclock::Now(); base_cycletime = cycleclock::Now();
base_walltime = Slow(); base_walltime = Slow();
...@@ -90,8 +90,7 @@ void Initialize() { ...@@ -90,8 +90,7 @@ void Initialize() {
} }
WallTime Now() { WallTime Now() {
if (!std::atomic_load(&initialized)) if (!std::atomic_load(&initialized)) return Slow();
return Slow();
WallTime now = 0.0; WallTime now = 0.0;
WallTime result = 0.0; WallTime result = 0.0;
...@@ -119,8 +118,8 @@ WallTime Now() { ...@@ -119,8 +118,8 @@ WallTime Now() {
return now; return now;
} }
std::string Print(WallTime time, const char *format, bool local, std::string Print(WallTime time, const char* format, bool local,
int *remainder_us) { int* remainder_us) {
char storage[32]; char storage[32];
struct tm split; struct tm split;
double subsecond; double subsecond;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment