@@ -1070,20 +1070,98 @@ static void random_memory(void *buf, size_t len)
10701070 }
10711071}
10721072
1073+ struct statistics {
1074+ long long start , finish , load_time ;
1075+ long long count , valid , too_slow , too_fast ;
1076+ long long min , max ;
1077+ double sum , sum2 , avg , mdev ;
1078+ double speed , iops , load_speed , load_iops ;
1079+ long long size , load_size ;
1080+ };
1081+
1082+ static void start_statistics (struct statistics * s , unsigned long long start ) {
1083+ memset (s , 0 , sizeof (* s ));
1084+ s -> min = LLONG_MAX ;
1085+ s -> max = LLONG_MIN ;
1086+ s -> start = start ;
1087+ }
1088+
1089+ static void add_statistics (struct statistics * s , long long val ) {
1090+ s -> count ++ ;
1091+ if (val < min_valid_time ) {
1092+ s -> too_fast ++ ;
1093+ } else if (val > max_valid_time ) {
1094+ s -> too_slow ++ ;
1095+ } else {
1096+ s -> valid ++ ;
1097+ s -> sum += val ;
1098+ s -> sum2 += (double )val * val ;
1099+ if (val < s -> min )
1100+ s -> min = val ;
1101+ if (val > s -> max )
1102+ s -> max = val ;
1103+ }
1104+ }
1105+
1106+ static void merge_statistics (struct statistics * s , struct statistics * o ) {
1107+ s -> count += o -> count ;
1108+ s -> too_fast += o -> too_fast ;
1109+ s -> too_slow += o -> too_slow ;
1110+ if (o -> valid ) {
1111+ s -> valid += o -> valid ;
1112+ s -> sum += o -> sum ;
1113+ s -> sum2 += o -> sum2 ;
1114+ if (o -> min < s -> min )
1115+ s -> min = o -> min ;
1116+ if (o -> max > s -> max )
1117+ s -> max = o -> max ;
1118+ }
1119+ }
1120+
1121+ static void finish_statistics (struct statistics * s , unsigned long long finish ) {
1122+ s -> finish = finish ;
1123+ s -> load_time = finish - s -> start ;
1124+
1125+ if (s -> valid ) {
1126+ s -> avg = s -> sum / s -> valid ;
1127+ s -> mdev = sqrt (s -> sum2 / s -> valid - s -> avg * s -> avg );
1128+ } else {
1129+ s -> min = 0 ;
1130+ s -> max = 0 ;
1131+ }
1132+
1133+ if (s -> sum )
1134+ s -> iops = (double )NSEC_PER_SEC * s -> valid / s -> sum ;
1135+
1136+ if (s -> load_time )
1137+ s -> load_iops = (double )NSEC_PER_SEC * s -> count / s -> load_time ;
1138+
1139+ s -> speed = s -> iops * size ;
1140+ s -> load_speed = s -> load_iops * size ;
1141+ s -> size = s -> valid * size ;
1142+ s -> load_size = s -> count * size ;
1143+ }
1144+
1145+ static void dump_statistics (struct statistics * s ) {
1146+ printf ("%lu %.0f %.0f %.0f %lu %.0f %lu %.0f %lu %lu\n" ,
1147+ (unsigned long )s -> valid , s -> sum ,
1148+ s -> iops , s -> speed ,
1149+ (unsigned long )s -> min , s -> avg ,
1150+ (unsigned long )s -> max , s -> mdev ,
1151+ (unsigned long )s -> count ,
1152+ (unsigned long )s -> load_time );
1153+ }
1154+
10731155int main (int argc , char * * argv )
10741156{
10751157 ssize_t ret_size ;
10761158 struct stat st ;
10771159 int ret ;
10781160
1079- long long request , part_request ;
1080- long long too_fast = 0 , too_slow = 0 ;
1081- long long total_valid , part_valid ;
1082- long long time_start , time_total , this_time ;
1083- double part_min , part_max , time_min , time_max ;
1084- double time_sum , time_sum2 , time_mdev , time_avg ;
1085- double part_sum , part_sum2 , part_mdev , part_avg ;
1086- long long time_now , time_next , part_start , period_deadline ;
1161+ struct statistics part , total ;
1162+
1163+ long long request , this_time ;
1164+ long long time_now , time_next , period_deadline ;
10871165
10881166 setvbuf (stdout , NULL , _IOLBF , 0 );
10891167
@@ -1248,30 +1326,22 @@ int main (int argc, char **argv)
12481326 set_signal ();
12491327
12501328 request = 0 ;
1251- total_valid = 0 ;
12521329 woffset = 0 ;
12531330
1254- part_request = 0 ;
1255- part_valid = 0 ;
1256-
1257- part_min = time_min = LLONG_MAX ;
1258- part_max = time_max = LLONG_MIN ;
1259- part_sum = time_sum = 0 ;
1260- part_sum2 = time_sum2 = 0 ;
1331+ time_now = now ();
12611332
1262- time_start = now ( );
1263- part_start = time_start ;
1333+ start_statistics ( & part , time_now );
1334+ start_statistics ( & total , time_now ) ;
12641335
12651336 if (deadline )
1266- deadline += time_start ;
1337+ deadline += time_now ;
12671338
1268- period_deadline = time_start + period_time ;
1339+ period_deadline = time_now + period_time ;
12691340
1270- time_next = time_start ;
1341+ time_next = time_now ;
12711342
12721343 while (!exiting ) {
12731344 request ++ ;
1274- part_request ++ ;
12751345
12761346 if (randomize )
12771347 woffset = random64 () % (wsize / size ) * size ;
@@ -1297,6 +1367,7 @@ int main (int argc, char **argv)
12971367 this_time = now ();
12981368
12991369 ret_size = make_request (fd , buf , size , offset + woffset );
1370+
13001371 if (ret_size < 0 ) {
13011372 if (errno != EINTR )
13021373 err (3 , "request failed" );
@@ -1315,18 +1386,9 @@ int main (int argc, char **argv)
13151386
13161387 if (request == 1 ) {
13171388 /* warmup */
1318- } else if (this_time < min_valid_time ) {
1319- too_fast ++ ;
1320- } else if (this_time > max_valid_time ) {
1321- too_slow ++ ;
1389+ part .count ++ ;
13221390 } else {
1323- part_valid ++ ;
1324- part_sum += this_time ;
1325- part_sum2 += this_time * this_time ;
1326- if (this_time < part_min )
1327- part_min = this_time ;
1328- if (this_time > part_max )
1329- part_max = this_time ;
1391+ add_statistics (& part , this_time );
13301392 }
13311393
13321394 if (!quiet ) {
@@ -1343,9 +1405,9 @@ int main (int argc, char **argv)
13431405 printf (" (too fast)" );
13441406 } else if (this_time > max_valid_time ) {
13451407 printf (" (too slow)" );
1346- } else if (part_valid > 5 && part_min < part_max ) {
1347- int percent = (this_time - part_min ) * 100 /
1348- (part_max - part_min );
1408+ } else if (part . valid > 5 && part . min < part . max ) {
1409+ int percent = (this_time - part . min ) * 100 /
1410+ (part . max - part . min );
13491411 if (percent < 5 )
13501412 printf (" (fast)" );
13511413 else if (percent > 95 )
@@ -1354,48 +1416,13 @@ int main (int argc, char **argv)
13541416 printf ("\n" );
13551417 }
13561418
1357- if ((period_request && (part_request >= period_request )) ||
1419+ if ((period_request && (part . count >= period_request )) ||
13581420 (period_time && (time_next >= period_deadline ))) {
1359-
1360- time_sum += part_sum ;
1361- time_sum2 += part_sum2 ;
1362- if (part_min < time_min )
1363- time_min = part_min ;
1364- if (part_max > time_max )
1365- time_max = part_max ;
1366-
1367- if (part_valid ) {
1368- part_avg = part_sum / part_valid ;
1369- part_mdev = sqrt (part_sum2 / part_valid -
1370- part_avg * part_avg );
1371- } else {
1372- part_min = 0 ;
1373- part_avg = 0 ;
1374- part_max = 0 ;
1375- part_mdev = 0 ;
1376- part_sum = 0.1 ;
1377- }
1378-
1379- printf ("%lu %.0f %.0f %.0f %.0f %.0f %.0f %.0f %lu %lu\n" ,
1380- (unsigned long )part_valid , part_sum ,
1381- 1. * NSEC_PER_SEC *
1382- part_valid / part_sum ,
1383- 1. * NSEC_PER_SEC *
1384- part_valid * size / part_sum ,
1385- part_min , part_avg ,
1386- part_max , part_mdev ,
1387- (unsigned long )part_request ,
1388- (unsigned long )(time_now - part_start ));
1389-
1390- part_min = LLONG_MAX ;
1391- part_max = LLONG_MIN ;
1392- part_sum = part_sum2 = 0 ;
1393- part_request = 0 ;
1394- total_valid += part_valid ;
1395- part_valid = 0 ;
1396-
1397- part_start = time_now ;
1398- period_deadline = part_start + period_time ;
1421+ finish_statistics (& part , time_now );
1422+ dump_statistics (& part );
1423+ merge_statistics (& total , & part );
1424+ start_statistics (& part , time_now );
1425+ period_deadline = time_now + period_time ;
13991426 }
14001427
14011428 if (!randomize ) {
@@ -1423,87 +1450,63 @@ int main (int argc, char **argv)
14231450 }
14241451
14251452 time_now = now ();
1426- time_total = time_now - time_start ;
1427- if (!time_total )
1428- time_total = 1 ;
1429-
1430- time_sum += part_sum ;
1431- time_sum2 += part_sum2 ;
1432- if (part_min < time_min )
1433- time_min = part_min ;
1434- if (part_max > time_max )
1435- time_max = part_max ;
1436- total_valid += part_valid ;
1437-
1438- if (total_valid ) {
1439- time_avg = time_sum / total_valid ;
1440- time_mdev = sqrt (time_sum2 / total_valid - time_avg * time_avg );
1441- } else {
1442- time_min = 0 ;
1443- time_avg = 0 ;
1444- time_max = 0 ;
1445- time_mdev = 0 ;
1446- time_sum = 0.1 ;
1447- }
1453+ finish_statistics (& part , time_now );
1454+ merge_statistics (& total , & part );
1455+ finish_statistics (& total , time_now );
14481456
14491457 if (batch_mode ) {
1450- printf ("%lu %.0f %.0f %.0f %.0f %.0f %.0f %.0f %lu %lu\n" ,
1451- (unsigned long )total_valid , time_sum ,
1452- 1. * NSEC_PER_SEC *
1453- total_valid / time_sum ,
1454- 1. * NSEC_PER_SEC *
1455- total_valid * size / time_sum ,
1456- time_min , time_avg ,
1457- time_max , time_mdev ,
1458- (unsigned long )request ,
1459- (unsigned long )time_total );
1460- } else if (!quiet || (!period_time && !period_request )) {
1461- printf ("\n--- %s (%s %s" , path , fstype , device );
1462- if (device_size )
1463- print_size (device_size );
1464- printf (") ioping statistics ---\n" );
1465- print_int (total_valid );
1466- printf (" requests completed in " );
1467- print_time (time_sum );
1468- printf (", " );
1469- print_size ((long long )total_valid * size );
1470- printf (" %s, " , write_read_test ? "transferred" :
1471- write_test ? "written" : "read" );
1472- print_int (1. * NSEC_PER_SEC * total_valid / time_sum );
1473- printf (" iops, " );
1474- print_size (1. * NSEC_PER_SEC * total_valid * size / time_sum );
1475- printf ("/s\n" );
1476-
1477- if (too_fast ) {
1478- print_int (too_fast );
1479- printf (" too fast, " );
1480- }
1481- if (too_slow ) {
1482- print_int (too_slow );
1483- printf (" too slow, " );
1484- }
1485- printf ("total " );
1486- print_int (request );
1487- printf (" requests in " );
1488- print_time (time_total );
1489- printf (", " );
1490- print_size ((long long )request * size );
1491- printf (", " );
1492- print_int (1. * NSEC_PER_SEC * request / time_total );
1493- printf (" iops, " );
1494- print_size (1. * NSEC_PER_SEC * request * size / time_total );
1495- printf ("/s\n" );
1496-
1497- printf ("min/avg/max/mdev = " );
1498- print_time (time_min );
1499- printf (" / " );
1500- print_time (time_avg );
1501- printf (" / " );
1502- print_time (time_max );
1503- printf (" / " );
1504- print_time (time_mdev );
1505- printf ("\n" );
1458+ dump_statistics (& total );
1459+ return 0 ;
1460+ }
1461+
1462+ if (quiet && (period_time || period_request ))
1463+ return 0 ;
1464+
1465+ printf ("\n--- %s (%s %s" , path , fstype , device );
1466+ if (device_size )
1467+ print_size (device_size );
1468+ printf (") ioping statistics ---\n" );
1469+ print_int (total .valid );
1470+ printf (" requests completed in " );
1471+ print_time (total .sum );
1472+ printf (", " );
1473+ print_size (total .size );
1474+ printf ("%s, " , write_read_test ? "" :
1475+ write_test ? " written" : " read" );
1476+ print_int (total .iops );
1477+ printf (" iops, " );
1478+ print_size (total .speed );
1479+ printf ("/s\n" );
1480+
1481+ if (total .too_fast ) {
1482+ print_int (total .too_fast );
1483+ printf (" too fast, " );
1484+ }
1485+ if (total .too_slow ) {
1486+ print_int (total .too_slow );
1487+ printf (" too slow, " );
15061488 }
1489+ printf ("generated " );
1490+ print_int (total .count );
1491+ printf (" requests in " );
1492+ print_time (total .load_time );
1493+ printf (", " );
1494+ print_size (total .load_size );
1495+ printf (", " );
1496+ print_int (total .load_iops );
1497+ printf (" iops, " );
1498+ print_size (total .load_speed );
1499+ printf ("/s\n" );
1500+
1501+ printf ("min/avg/max/mdev = " );
1502+ print_time (total .min );
1503+ printf (" / " );
1504+ print_time (total .avg );
1505+ printf (" / " );
1506+ print_time (total .max );
1507+ printf (" / " );
1508+ print_time (total .mdev );
1509+ printf ("\n" );
15071510
15081511 return 0 ;
15091512}
0 commit comments