4242
4343#define ENOUGH_MEASURE 10000
4444#define TEST_TRIES 10
45+ #define NUM_PERCENTILES (100)
4546
4647static t_context_t * t ;
4748
@@ -56,6 +57,30 @@ static void __attribute__((noreturn)) die(void)
5657 exit (111 );
5758}
5859
60+ static int64_t percentile (const int64_t * a_sorted , double which , size_t size )
61+ {
62+ assert (which >= 0 && which <= 1.0 );
63+ size_t pos = (size_t ) (which * size );
64+ return a_sorted [pos ];
65+ }
66+
67+ static int cmp (const int64_t * a , const int64_t * b )
68+ {
69+ return * a - * b ;
70+ }
71+
72+ static void prepare_percentiles (int64_t * exec_times , int64_t * percentiles )
73+ {
74+ qsort (exec_times , N_MEASURES , sizeof (int64_t ),
75+ (int (* )(const void * , const void * )) cmp );
76+
77+ for (size_t i = 0 ; i < NUM_PERCENTILES ; i ++ ) {
78+ percentiles [i ] = percentile (
79+ exec_times , 1 - (pow (0.5 , 10 * (double ) (i + 1 ) / NUM_PERCENTILES )),
80+ N_MEASURES );
81+ }
82+ }
83+
5984static void differentiate (int64_t * exec_times ,
6085 const int64_t * before_ticks ,
6186 const int64_t * after_ticks )
@@ -64,7 +89,9 @@ static void differentiate(int64_t *exec_times,
6489 exec_times [i ] = after_ticks [i ] - before_ticks [i ];
6590}
6691
67- static void update_statistics (const int64_t * exec_times , uint8_t * classes )
92+ static void update_statistics (const int64_t * exec_times ,
93+ uint8_t * classes ,
94+ int64_t * percentiles )
6895{
6996 for (size_t i = 0 ; i < N_MEASURES ; i ++ ) {
7097 int64_t difference = exec_times [i ];
@@ -74,6 +101,13 @@ static void update_statistics(const int64_t *exec_times, uint8_t *classes)
74101
75102 /* do a t-test on the execution time */
76103 t_push (t , difference , classes [i ]);
104+
105+ // t-test on cropped execution times, for several cropping thresholds.
106+ for (size_t j = 0 ; j < NUM_PERCENTILES ; j ++ ) {
107+ if (difference < percentiles [j ]) {
108+ t_push (t , difference , classes [i ]);
109+ }
110+ }
77111 }
78112}
79113
@@ -123,6 +157,7 @@ static bool doit(int mode)
123157 int64_t * exec_times = calloc (N_MEASURES , sizeof (int64_t ));
124158 uint8_t * classes = calloc (N_MEASURES , sizeof (uint8_t ));
125159 uint8_t * input_data = calloc (N_MEASURES * CHUNK_SIZE , sizeof (uint8_t ));
160+ int64_t * percentiles = calloc (NUM_PERCENTILES , sizeof (int64_t ));
126161
127162 if (!before_ticks || !after_ticks || !exec_times || !classes ||
128163 !input_data ) {
@@ -133,14 +168,16 @@ static bool doit(int mode)
133168
134169 bool ret = measure (before_ticks , after_ticks , input_data , mode );
135170 differentiate (exec_times , before_ticks , after_ticks );
136- update_statistics (exec_times , classes );
171+ prepare_percentiles (exec_times , percentiles );
172+ update_statistics (exec_times , classes , percentiles );
137173 ret &= report ();
138174
139175 free (before_ticks );
140176 free (after_ticks );
141177 free (exec_times );
142178 free (classes );
143179 free (input_data );
180+ free (percentiles );
144181
145182 return ret ;
146183}
0 commit comments