@@ -189,11 +189,61 @@ static void test_overflow_detection(void) {
189189 "Safe calculation: %.3e < %.3e" , safe_product , (double )UINT64_MAX );
190190}
191191
192+ /* Test precision for long running scenarios */
193+ static void test_long_running_precision (void ) {
194+ tap_diag ("Testing long running precision" );
195+ /* This tests fio's ability to accurately recover per second latency values
196+ * from running average latency values. Fio estimates per second average
197+ * latency by calculating the following:
198+ *
199+ * total_latency_t1 = average_latency_t1 * samples_t1
200+ * total_latency_t2 = average_latency_t2 * samples_t2
201+ *
202+ * per_second_latency = (total_latency_t2 - total_latency_t1) / (samples_t2 - samples_t1)
203+ *
204+ * The question is whether there is enough precision in average_latency_t1
205+ * and average_latency_t2 to accurately recover per_second_latency,
206+ * especially when samples_t1 and samples_t2 are very large.
207+ */
208+
209+ /* Test 13: Sanity check with average from long run */
210+ uint64_t samples = 884660191700ULL ;
211+ uint64_t prev_samples = samples ;
212+ double total_latency = 13465068.0 * (double )samples ;
213+ double average_latency = total_latency / (double )samples ;
214+
215+ tap_ok (fabs (average_latency - 13465068.0 ) < 0.001 * average_latency ,
216+ "Long run average latency accurate: %.6f ns" , average_latency );
217+
218+ /* Run for one more second and see if we can detect per second average latency */
219+ /* Simulate IOs with 13000000ns mean latency in the next second */
220+ double val = 13000000 ;
221+ uint64_t new_samples = 134000 ;
222+ for (uint64_t i = 0 ; i < new_samples ; i ++ ) {
223+ /* from stat.c:add_stat_sample() */
224+ double delta = val - average_latency ;
225+ if (delta )
226+ average_latency += delta / (samples + 1.0 );
227+ samples ++ ;
228+ };
229+
230+ /* Test 14: make sure sample size is correct */
231+ tap_ok (samples == prev_samples + new_samples ,
232+ "Long run samples correct: %lu" , samples );
233+
234+ /* Test 15: make sure per second average latency is reasonable */
235+ double lat_sum = average_latency * (double )samples ;
236+ double per_second_latency = (lat_sum - total_latency ) / (double )new_samples ;
237+ tap_ok (fabs (per_second_latency - 13000000.0 ) < 0.001 * per_second_latency ,
238+ "Long run per second latency accurate: %.6f ns" , per_second_latency );
239+ }
240+
241+
192242int main (void ) {
193243 tap_init ();
194244
195- /* We have 12 tests total */
196- tap_plan (12 );
245+ /* We have 15 tests total */
246+ tap_plan (15 );
197247
198248 tap_diag ("=== FIO Latency Precision Mock Test ===" );
199249 tap_diag ("Testing numerical precision improvements in steady state calculations" );
@@ -203,6 +253,7 @@ int main(void) {
203253 test_accumulation_precision ();
204254 test_precision_improvements ();
205255 test_overflow_detection ();
256+ test_long_running_precision ();
206257
207258 return tap_done ();
208259}
0 commit comments