Skip to content

Commit

Permalink
f3write: add a backup speed measurement
Browse files Browse the repository at this point in the history
If the drive is too fast for the measument of the flow algorithm,
this patch uses a coarse approximation of the writing speed.
  • Loading branch information
AltraMayor committed May 16, 2019
1 parent 62ef992 commit c9eee71
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
39 changes: 31 additions & 8 deletions f3write.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,17 @@ static void erase(int count)
repeat_ch('\b', count);
}

static inline double get_avg_speed_given_time(struct flow *fw,
uint64_t total_time_ms)
{
return (double)(fw->measured_blocks * fw->block_size * 1000) /
total_time_ms;
}

/* Average writing speed in byte/s. */
static inline double get_avg_speed(struct flow *fw)
{
return (double)(fw->measured_blocks * fw->block_size * 1000) /
fw->measured_time_ms;
return get_avg_speed_given_time(fw, fw->measured_time_ms);
}

static int pr_time(double sec)
Expand Down Expand Up @@ -337,7 +343,7 @@ static int measure(int fd, struct flow *fw, ssize_t written)
{
ldiv_t result = ldiv(written, fw->block_size);
struct timeval t2;
long delay;
int64_t delay;
double bytes_k, inst_speed;

assert(result.rem == 0);
Expand Down Expand Up @@ -594,13 +600,20 @@ static inline void pr_freespace(uint64_t fs)
printf("Free space: %.2f %s\n", f, unit);
}

static inline void pr_avg_speed(double speed)
{
const char *unit = adjust_unit(&speed);
printf("Average writing speed: %.2f %s/s\n", speed, unit);
}

static int fill_fs(const char *path, long start_at, long end_at,
long max_write_rate, int progress)
{
uint64_t free_space;
struct flow fw;
long i;
int has_suggested_max_write_rate = max_write_rate > 0;
struct timeval t1, t2;

free_space = get_freespace(path);
pr_freespace(free_space);
Expand Down Expand Up @@ -628,20 +641,30 @@ static int fill_fs(const char *path, long start_at, long end_at,
}

init_flow(&fw, free_space, max_write_rate, progress);
assert(!gettimeofday(&t1, NULL));
for (i = start_at; i <= end_at; i++)
if (create_and_fill_file(path, i, GIGABYTES,
&has_suggested_max_write_rate, &fw))
break;
assert(!gettimeofday(&t2, NULL));

/* Final report. */
pr_freespace(get_freespace(path));
/* Writing speed. */
if (fw.measured_time_ms > fw.delay_ms) {
double speed = get_avg_speed(&fw);
const char *unit = adjust_unit(&speed);
printf("Average writing speed: %.2f %s/s\n", speed, unit);
} else
printf("Writing speed not available\n");
pr_avg_speed(get_avg_speed(&fw));
} else {
/* If the drive is too fast for the measuments above,
* try a coarse approximation of the writing speed.
*/
int64_t total_time_ms = delay_ms(&t1, &t2);
if (total_time_ms > 0) {
pr_avg_speed(get_avg_speed_given_time(&fw,
total_time_ms));
} else {
printf("Writing speed not available\n");
}
}

return 0;
}
Expand Down
7 changes: 4 additions & 3 deletions utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ int is_my_file(const char *filename);
/* Caller must free(3) the returned pointer. */
char *full_fn_from_number(const char **filename, const char *path, long num);

static inline long delay_ms(const struct timeval *t1, const struct timeval *t2)
static inline int64_t delay_ms(const struct timeval *t1,
const struct timeval *t2)
{
return (t2->tv_sec - t1->tv_sec) * 1000 +
(t2->tv_usec - t1->tv_usec) / 1000;
return (int64_t)(t2->tv_sec - t1->tv_sec) * 1000 +
(t2->tv_usec - t1->tv_usec) / 1000;
}

const long *ls_my_files(const char *path, long start_at, long end_at);
Expand Down

0 comments on commit c9eee71

Please sign in to comment.