diff --git a/f3probe.c b/f3probe.c index 969ee9f..bb8e6ff 100644 --- a/f3probe.c +++ b/f3probe.c @@ -348,18 +348,24 @@ static void report_cache(const char *prefix, uint64_t cache_size_block, need_reset ? "yes" : "no"); } +static void report_probe_time(const char *prefix, uint64_t usec) +{ + char str[TIME_STR_SIZE]; + usec_to_str(usec, str); + printf("%s %s\n", prefix, str); +} + static void report_ops(const char *op, uint64_t count, uint64_t time_us) { - printf("Probe %s op: count=%" PRIu64 - ", total time=%.2fs, avg op time=%.2fms\n", - op, count, time_us / 1e6, - count > 0 ? (time_us / count) / 1e3 : 0.0); + char str1[TIME_STR_SIZE], str2[TIME_STR_SIZE]; + usec_to_str(time_us, str1); + usec_to_str(count > 0 ? time_us / count : 0, str2); + printf("%10s: %s / %" PRIu64 " = %s\n", op, str1, count, str2); } static int test_device(struct args *args) { struct timeval t1, t2; - double time_s; struct device *dev, *pdev, *sdev; enum fake_type fake_type; uint64_t real_size_byte, announced_size_byte, cache_size_block; @@ -479,7 +485,6 @@ static int test_device(struct args *args) break; } - time_s = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec)/1000000.; printf("\nDevice geometry:\n"); report_size("\t *Usable* size:", real_size_byte, block_order); @@ -489,12 +494,13 @@ static int test_device(struct args *args) report_cache("\tApproximate cache size:", cache_size_block, need_reset, block_order); report_order("\t Physical block size:", block_order); - printf("\nProbe time: %.2f seconds\n", time_s); + report_probe_time("\nProbe time:", diff_timeval_us(&t1, &t2)); if (args->time_ops) { - report_ops("read", read_count, read_time_us); - report_ops("write", write_count, write_time_us); - report_ops("reset", reset_count, reset_time_us); + printf(" Operation: total time / count = avg time\n"); + report_ops("Read", read_count, read_time_us); + report_ops("Write", write_count, write_time_us); + report_ops("Reset", reset_count, reset_time_us); } free((void *)final_dev_filename); diff --git a/libutils.c b/libutils.c index 7485c3c..95d3d3a 100644 --- a/libutils.c +++ b/libutils.c @@ -59,6 +59,83 @@ const char *adjust_unit(double *ptr_bytes) return units[i]; } +#define USEC_IN_A_MSEC 1000ULL +#define USEC_IN_A_SEC (1000*USEC_IN_A_MSEC) +#define USEC_IN_A_MIN (60*USEC_IN_A_SEC) +#define USEC_IN_AN_HOUR (60*USEC_IN_A_MIN) +#define USEC_IN_A_DAY (24*USEC_IN_AN_HOUR) + +int usec_to_str(uint64_t usec, char *str) +{ + int has_d, has_h, has_m, has_s; + lldiv_t div; + int c, tot = 0; + + has_d = usec >= USEC_IN_A_DAY; + if (has_d) { + div = lldiv(usec, USEC_IN_A_DAY); + usec = div.rem; + c = sprintf(str + tot, "%i days", (int)div.quot); + assert(c > 0); + tot += c; + } + + has_h = usec >= USEC_IN_AN_HOUR; + if (has_h) { + div = lldiv(usec, USEC_IN_AN_HOUR); + usec = div.rem; + c = sprintf(str + tot, "%s%i:", + has_d ? " " : "", (int)div.quot); + assert(c > 0); + tot += c; + } + + has_m = has_h || usec >= USEC_IN_A_MIN; + if (has_m) { + div = lldiv(usec, USEC_IN_A_MIN); + usec = div.rem; + if (has_h) + c = sprintf(str + tot, "%02i", (int)div.quot); + else + c = sprintf(str + tot, "%i'", (int)div.quot); + assert(c > 0); + tot += c; + } + + has_s = usec >= USEC_IN_A_SEC; + if (has_s) { + div = lldiv(usec, USEC_IN_A_SEC); + usec = div.rem; + if (has_h) + c = sprintf(str + tot, ":%02i", (int)div.quot); + else if (has_m) + c = sprintf(str + tot, "%02i\"", (int)div.quot); + else if (has_d) + c = sprintf(str + tot, "%is", (int)div.quot); + else + c = sprintf(str + tot, "%i.%02is", (int)div.quot, + (int)(usec / (10 * USEC_IN_A_MSEC))); + assert(c > 0); + tot += c; + } + + if (has_d || has_h || has_m || has_s) + return tot; + + if (usec >= USEC_IN_A_MSEC) { + div = lldiv(usec, USEC_IN_A_MSEC); + usec = div.rem; + c = sprintf(str + tot, "%i.%ims", (int)div.quot, + (int)(usec / 100)); + } else { + c = sprintf(str + tot, "%ius", (int)usec); + } + assert(c > 0); + tot += c; + + return tot; +} + void *align_mem(void *p, int order) { uintptr_t ip = (uintptr_t)p; diff --git a/libutils.h b/libutils.h index 2c76219..18dd137 100644 --- a/libutils.h +++ b/libutils.h @@ -16,6 +16,10 @@ int ceiling_log2(uint64_t x); const char *adjust_unit(double *ptr_bytes); +#define TIME_STR_SIZE 128 + +int usec_to_str(uint64_t usec, char *str); + /* * The functions align_head() and align_mem() are used to align pointers. *