1 /* FLAC - Free Lossless Audio Codec
2 * Copyright (C) 2015-2016 Xiph.Org Foundation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * - Neither the name of the Xiph.org Foundation nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 counter_diff (const LARGE_INTEGER
* start
, const LARGE_INTEGER
* end
)
46 LARGE_INTEGER diff
, freq
;
48 QueryPerformanceFrequency(&freq
);
49 diff
.QuadPart
= end
->QuadPart
- start
->QuadPart
;
51 return (double)diff
.QuadPart
/(double)freq
.QuadPart
;
55 benchmark_function (void (*testfunc
) (void), unsigned count
)
57 LARGE_INTEGER start
, end
;
60 QueryPerformanceCounter (&start
) ;
62 for (k
= 0 ; k
< count
; k
++)
65 QueryPerformanceCounter (&end
) ;
67 return counter_diff (&start
, &end
) / count
;
68 } /* benchmark_function */
70 #elif defined FLAC__SYS_DARWIN
72 #include <mach/mach_time.h>
75 counter_diff (const uint64_t * start
, const uint64_t * end
)
77 mach_timebase_info_data_t t_info
;
78 mach_timebase_info(&t_info
);
79 uint64_t duration
= *end
- *start
;
81 return duration
* ((double)t_info
.numer
/(double)t_info
.denom
);
85 benchmark_function (void (*testfunc
) (void), unsigned count
)
90 start
= mach_absolute_time();
92 for (k
= 0 ; k
< count
; k
++)
95 end
= mach_absolute_time();
97 return counter_diff (&start
, &end
) / count
;
98 } /* benchmark_function */
100 #elif defined HAVE_CLOCK_GETTIME
103 #include <sys/time.h>
106 timespec_diff (const struct timespec
* start
, const struct timespec
* end
)
107 { struct timespec diff
;
109 if (end
->tv_nsec
- start
->tv_nsec
< 0)
110 { diff
.tv_sec
= end
->tv_sec
- start
->tv_sec
- 1 ;
111 diff
.tv_nsec
= 1000000000 + end
->tv_nsec
- start
->tv_nsec
;
114 { diff
.tv_sec
= end
->tv_sec
- start
->tv_sec
;
115 diff
.tv_nsec
= end
->tv_nsec
-start
->tv_nsec
;
118 return diff
.tv_sec
+ 1e-9 * diff
.tv_nsec
;
122 benchmark_function (void (*testfunc
) (void), unsigned count
)
123 { struct timespec start
, end
;
126 clock_gettime (CLOCK_PROCESS_CPUTIME_ID
, &start
) ;
128 for (k
= 0 ; k
< count
; k
++)
131 clock_gettime (CLOCK_PROCESS_CPUTIME_ID
, &end
) ;
133 return timespec_diff (&start
, &end
) / count
;
134 } /* benchmark_function */
139 #include <sys/time.h>
142 timeval_diff (const struct timeval
* start
, const struct timeval
* end
)
143 { struct timeval diff
;
145 if (end
->tv_usec
- start
->tv_usec
< 0)
146 { diff
.tv_sec
= end
->tv_sec
- start
->tv_sec
- 1 ;
147 diff
.tv_usec
= 1000000 + end
->tv_usec
- start
->tv_usec
;
150 { diff
.tv_sec
= end
->tv_sec
- start
->tv_sec
;
151 diff
.tv_usec
= end
->tv_usec
-start
->tv_usec
;
154 return diff
.tv_sec
+ 1e-6 * diff
.tv_usec
;
158 benchmark_function (void (*testfunc
) (void), unsigned count
)
159 { struct timeval start
, end
;
162 gettimeofday(&start
, NULL
);
164 for (k
= 0 ; k
< count
; k
++)
167 gettimeofday(&end
, NULL
);
169 return timeval_diff (&start
, &end
) / count
;
170 } /* benchmark_function */
175 double_cmp (const void * a
, const void * b
)
176 { const double * pa
= (double *) a
;
177 const double * pb
= (double *) b
;
178 return pa
[0] < pb
[0] ;
182 benchmark_stats (bench_stats
* stats
)
183 { double sum
, times
[stats
->run_count
] ;
186 for (k
= 0 ; k
< stats
->run_count
; k
++)
187 times
[k
] = benchmark_function (stats
->testfunc
, stats
->loop_count
) ;
189 qsort (times
, stats
->run_count
, sizeof (times
[0]), double_cmp
) ;
192 stats
->min_time
= stats
->max_time
= times
[0] ;
193 for (k
= 0 ; k
< stats
->run_count
; k
++)
194 { stats
->min_time
= stats
->min_time
< times
[k
] ? stats
->min_time
: times
[k
] ;
195 stats
->max_time
= stats
->max_time
> times
[k
] ? stats
->max_time
: times
[k
] ;
198 stats
->mean_time
= sum
/ stats
->run_count
;
199 if (stats
->run_count
& 1)
200 stats
->median_time
= times
[(stats
->run_count
+ 1) / 2] ;
202 stats
->median_time
= 0.5 * (times
[stats
->run_count
/ 2] + times
[(stats
->run_count
/ 2) + 1]) ;
205 } /* benchmark_stats */