/* measure.h * Macros to help with performance measurement. * vi:ts=4 sw=4 * * (c) Copyright 2012 Hewlett-Packard Development Company, L.P. * 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. Algorithms used by * this code may be covered by patents by HP, Microsoft, or other parties. * * MEASURE_LOOP_START("measurement", 2000) * code to be measured * MEASURE_LOOP_STOP * buffer flush and such * MEASURE_SHOW_RESULTS * * Define GOOGLE_PROFILER if you want gperftools included. */ #ifndef TEST_MEASURE_H_INCLUDED #define TEST_MEASURE_H_INCLUDED #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifndef _WIN32 #include #endif #include #ifdef _WIN32 #define PROFILER_START(_prefix_) #define PROFILER_STOP #define MEASURE_LOOP_START(_prefix_, _count_) #define MEASURE_LOOP_STOP #define MEASURE_GET_RESULTS(_result_) #define MEASURE_SHOW_RESULTS(_result_) #define MEASURE_SHOW_RESULTS_SCALED(_scale_, _label_) #define MEASURE_TIMED(_label_, _init_iter_, _test_time_, _result_, _call_) #else #ifdef GOOGLE_PROFILER #include #define PROFILER_START(_prefix_) \ do \ { \ char _path[PATH_MAX]; \ sprintf_s(_path, sizeof(_path), "./%s.prof", (_prefix_)); \ ProfilerStart(_path); \ } while (0); #define PROFILER_STOP \ do \ { \ ProfilerStop(); \ } while (0); #else #define PROFILER_START(_prefix_) #define PROFILER_STOP #endif // GOOGLE_PROFILER extern float _delta_time(const struct timespec* t0, const struct timespec* t1); extern void _floatprint(float t, char* output); #ifndef CLOCK_MONOTONIC_RAW #define CLOCK_MONOTONIC_RAW 4 #endif // !CLOCK_MONOTONIC_RAW #define MEASURE_LOOP_START(_prefix_, _count_) \ { \ struct timespec _start, _stop; \ char* _prefix; \ int _count = (_count_); \ int _loop; \ float _delta; \ char _str1[32], _str2[32]; \ _prefix = strdup(_prefix_); \ _str1[0] = '\0'; \ _str2[0] = '\0'; \ clock_gettime(CLOCK_MONOTONIC_RAW, &_start); \ PROFILER_START(_prefix); \ _loop = (_count); \ do \ { #define MEASURE_LOOP_STOP \ } \ while (--_loop) \ ; #define MEASURE_GET_RESULTS(_result_) \ PROFILER_STOP; \ clock_gettime(CLOCK_MONOTONIC_RAW, &_stop); \ _delta = _delta_time(&_start, &_stop); \ (_result_) = (float)_count / _delta; \ free(_prefix); \ } #define MEASURE_SHOW_RESULTS(_result_) \ PROFILER_STOP; \ clock_gettime(CLOCK_MONOTONIC_RAW, &_stop); \ _delta = _delta_time(&_start, &_stop); \ (_result_) = (float)_count / _delta; \ _floatprint((float)_count / _delta, _str1); \ printf("%s: %9d iterations in %5.1f seconds = %s/s \n", _prefix, _count, _delta, _str1); \ free(_prefix); \ } #define MEASURE_SHOW_RESULTS_SCALED(_scale_, _label_) \ PROFILER_STOP; \ clock_gettime(CLOCK_MONOTONIC_RAW, &_stop); \ _delta = _delta_time(&_start, &_stop); \ _floatprint((float)_count / _delta, _str1); \ _floatprint((float)_count / _delta * (_scale_), _str2); \ printf("%s: %9d iterations in %5.1f seconds = %s/s = %s%s \n", _prefix, _count, _delta, _str1, \ _str2, _label_); \ free(_prefix); \ } #define MEASURE_TIMED(_label_, _init_iter_, _test_time_, _result_, _call_) \ { \ float _r; \ MEASURE_LOOP_START(_label_, _init_iter_); \ _call_; \ MEASURE_LOOP_STOP; \ MEASURE_GET_RESULTS(_r); \ MEASURE_LOOP_START(_label_, _r* _test_time_); \ _call_; \ MEASURE_LOOP_STOP; \ MEASURE_SHOW_RESULTS(_result_); \ } #endif #endif // __MEASURE_H_INCLUDED__