FreeRDP
measure.h
1 /* measure.h
2  * Macros to help with performance measurement.
3  * vi:ts=4 sw=4
4  *
5  * (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
6  * Licensed under the Apache License, Version 2.0 (the "License"); you may
7  * not use this file except in compliance with the License. You may obtain
8  * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12  * or implied. See the License for the specific language governing
13  * permissions and limitations under the License. Algorithms used by
14  * this code may be covered by patents by HP, Microsoft, or other parties.
15  *
16  * MEASURE_LOOP_START("measurement", 2000)
17  * code to be measured
18  * MEASURE_LOOP_STOP
19  * buffer flush and such
20  * MEASURE_SHOW_RESULTS
21  *
22  * Define GOOGLE_PROFILER if you want gperftools included.
23  */
24 
25 #ifndef TEST_MEASURE_H_INCLUDED
26 #define TEST_MEASURE_H_INCLUDED
27 
28 #include <freerdp/config.h>
29 
30 #include <time.h>
31 #include <winpr/string.h>
32 #include <winpr/sysinfo.h>
33 
34 #ifndef _WIN32
35 #include <sys/param.h>
36 #endif
37 
38 #include <winpr/crt.h>
39 
40 #ifdef _WIN32
41 
42 #define PROFILER_START(_prefix_)
43 #define PROFILER_STOP
44 
45 #define MEASURE_LOOP_START(_prefix_, _count_)
46 #define MEASURE_LOOP_STOP
47 #define MEASURE_GET_RESULTS(_result_)
48 #define MEASURE_SHOW_RESULTS(_result_)
49 #define MEASURE_SHOW_RESULTS_SCALED(_scale_, _label_)
50 #define MEASURE_TIMED(_label_, _init_iter_, _test_time_, _result_, _call_)
51 
52 #else
53 
54 #ifdef GOOGLE_PROFILER
55 #include <gperftools/profiler.h>
56 #define PROFILER_START(_prefix_) \
57  do \
58  { \
59  char _path[PATH_MAX]; \
60  sprintf_s(_path, sizeof(_path), "./%s.prof", (_prefix_)); \
61  ProfilerStart(_path); \
62  } while (0);
63 #define PROFILER_STOP \
64  do \
65  { \
66  ProfilerStop(); \
67  } while (0);
68 #else
69 #define PROFILER_START(_prefix_)
70 #define PROFILER_STOP
71 #endif // GOOGLE_PROFILER
72 
73 extern float measure_delta_time(UINT64 t0, UINT64 t1);
74 extern void measure_floatprint(float t, char* output, size_t len);
75 
76 #define MEASURE_LOOP_START(_prefix_, _count_) \
77  { \
78  int _count = (_count_); \
79  int _loop; \
80  char str1[32] = { 0 }; \
81  char str2[32] = { 0 }; \
82  char* _prefix = _strdup(_prefix_); \
83  const UINT64 start = winpr_GetTickCount64NS(); \
84  PROFILER_START(_prefix); \
85  _loop = (_count); \
86  do \
87  {
88 
89 #define MEASURE_LOOP_STOP \
90  } \
91  while (--_loop) \
92  ;
93 
94 #define MEASURE_GET_RESULTS(_result_) \
95  PROFILER_STOP; \
96  const UINT64 stop = winpr_GetTickCount64NS(); \
97  const float delta = measure_delta_time(start, stop); \
98  (_result_) = (float)_count / delta; \
99  free(_prefix); \
100  }
101 
102 #define MEASURE_SHOW_RESULTS(_result_) \
103  PROFILER_STOP; \
104  const UINT64 stop = winpr_GetTickCount64NS(); \
105  const float delta = measure_delta_time(start, stop); \
106  (_result_) = (float)_count / delta; \
107  measure_floatprint((float)_count / delta, str1); \
108  printf("%s: %9d iterations in %5.1f seconds = %s/s \n", _prefix, _count, delta, str1); \
109  free(_prefix); \
110  }
111 
112 #define MEASURE_SHOW_RESULTS_SCALED(_scale_, _label_) \
113  PROFILER_STOP; \
114  const UINT64 stop = winpr_GetTickCount64NS(); \
115  const float delta = measure_delta_time(start, stop); \
116  measure_floatprint((float)_count / delta, str1); \
117  measure_floatprint((float)_count / delta * (_scale_), str2); \
118  printf("%s: %9d iterations in %5.1f seconds = %s/s = %s%s \n", _prefix, _count, delta, str1, \
119  str2, _label_); \
120  free(_prefix); \
121  }
122 
123 #define MEASURE_TIMED(_label_, _init_iter_, _test_time_, _result_, _call_) \
124  { \
125  float _r; \
126  MEASURE_LOOP_START(_label_, _init_iter_); \
127  _call_; \
128  MEASURE_LOOP_STOP; \
129  MEASURE_GET_RESULTS(_r); \
130  MEASURE_LOOP_START(_label_, _r* _test_time_); \
131  _call_; \
132  MEASURE_LOOP_STOP; \
133  MEASURE_SHOW_RESULTS(_result_); \
134  }
135 
136 #endif
137 
138 #endif // __MEASURE_H_INCLUDED__