BeBOP Optimized Sparse Kernel Interface Library
1.0.1h
|
00001 00007 #if !defined(INC_UTIL_TIMING_H) 00008 00009 #define INC_UTIL_TIMING_H 00010 00011 #include <oski/timer.h> 00012 #include "stat.h" 00013 00048 #define TIMING_LOOP_CORE( CODE, PRE_CODE, POST_CODE, outer_iters, inner_iters, times ) \ 00049 { \ 00050 oski_timer_t timer_; \ 00051 \ 00052 size_t i_outer_; \ 00053 \ 00054 /* Allocate timer and space for outer iteration times. */ \ 00055 timer_ = oski_CreateTimer(); \ 00056 ABORT( timer_ == NULL, TIMING_LOOP_CORE, ERR_OUT_OF_MEMORY ); \ 00057 ABORT( (times) == NULL, TIMING_LOOP_CORE, ERR_BAD_ARG ); \ 00058 ABORT( (inner_iters) <= 0, TIMING_LOOP_CORE, ERR_BAD_ARG ); \ 00059 \ 00060 for( i_outer_ = 0; i_outer_ < (outer_iters); i_outer_++ ) \ 00061 { \ 00062 size_t i_inner; \ 00063 { \ 00064 PRE_CODE; \ 00065 } \ 00066 oski_RestartTimer( timer_ ); \ 00067 for( i_inner = 0; i_inner < (inner_iters); i_inner++ ) \ 00068 { \ 00069 CODE; \ 00070 } \ 00071 oski_StopTimer( timer_ ); \ 00072 { \ 00073 POST_CODE; \ 00074 } \ 00075 (times)[i_outer_] = oski_ReadElapsedTime(timer_) / (inner_iters); \ 00076 } \ 00077 \ 00078 oski_DestroyTimer( timer_ ); \ 00079 } 00080 00093 #define CALC_MIN_ITERS( CODE, PRE_CODE, POST_CODE, min_time, num_iters ) \ 00094 { \ 00095 size_t inner_iters_ = 0; \ 00096 oski_timer_t timer_ = oski_CreateTimer(); \ 00097 double t_cumulative_ = 0.0; /* time so far ... */ \ 00098 \ 00099 oski_PrintDebugMessage( 1, \ 00100 "Estimating minimum # of inner iterations needed" \ 00101 " to get %g seconds of execution time...", \ 00102 (double)min_time ); \ 00103 \ 00104 ABORT( timer_ == NULL, CALC_MIN_ITERS, ERR_OUT_OF_MEMORY ); \ 00105 \ 00106 do \ 00107 { \ 00108 size_t i_inner; \ 00109 inner_iters_ = (inner_iters_ == 0) ? 1 : 2*inner_iters_; \ 00110 { \ 00111 PRE_CODE; \ 00112 } \ 00113 oski_RestartTimer( timer_ ); \ 00114 for( i_inner = 0; i_inner < inner_iters_; i_inner++ ) \ 00115 { \ 00116 CODE; \ 00117 } \ 00118 oski_StopTimer( timer_ ); \ 00119 { \ 00120 POST_CODE; \ 00121 } \ 00122 t_cumulative_ += oski_ReadElapsedTime( timer_ ); \ 00123 } while( t_cumulative_ < (min_time) ); \ 00124 \ 00125 oski_DestroyTimer( timer_ ); \ 00126 \ 00127 /* return */ \ 00128 oski_PrintDebugMessage( 1, "Need at least %d inner iterations.", \ 00129 inner_iters_ ); \ 00130 (num_iters) = inner_iters_; \ 00131 } 00132 00134 #define DUMMY_CODE 00135 00147 #define TIMING_LOOP_BASIC( CODE, num_trials, num_ops, speed ) \ 00148 { \ 00149 double* outer_times_; \ 00150 size_t min_inner_; \ 00151 \ 00152 outer_times_ = oski_Malloc( double, (num_trials) ); \ 00153 ABORT( outer_times_ == NULL, TIMING_LOOP_BASIC, ERR_OUT_OF_MEMORY ); \ 00154 \ 00155 CALC_MIN_ITERS( CODE, DUMMY_CODE, DUMMY_CODE, .2, min_inner_ ); \ 00156 TIMING_LOOP_CORE( CODE, DUMMY_CODE, DUMMY_CODE, \ 00157 (num_trials), min_inner_, outer_times_ ); \ 00158 (speed) = \ 00159 (double)(num_ops) / stat_CalcMin(outer_times_, num_trials); \ 00160 \ 00161 oski_Free( outer_times_ ); \ 00162 } 00163 00164 #endif 00165 00166 /* eof */