#include "test_utils.h" static int test_single_file_random_perf(const char *path) { size_t io_size = 128 * 1024; size_t max_size = 2ULL * 1024 * 1024 * 1024; size_t max_count = max_size / io_size; int test_sec = 10; int direct = 0; printf("\n=== test_single_file_random_perf ===\n"); printf("Path : %s\n", path); printf("IO size : %zu KB\n", io_size / 1024); printf("Range : %zu MB\n", max_size / 1024 / 1024); printf("Duration: %d sec\n", test_sec); srand(0x1234); char *buf = aligned_alloc(4096, io_size); if (!buf) { perror("aligned_alloc"); return 1; } memset(buf, 'A', io_size); struct timespec t1, t2, now; unlink(path); int fd = open(path, O_CREAT | O_RDWR | direct, 0644); if (fd < 0) { perror("open rand write"); free(buf); return 2; } clock_gettime(CLOCK_MONOTONIC, &t1); size_t wcount = 0; do { size_t blk = rand() % max_count; off_t offset = (off_t)blk * io_size; if (lseek(fd, offset, SEEK_SET) < 0) { perror("lseek rand write"); close(fd); free(buf); return 3; } if (write(fd, buf, io_size) != (ssize_t)io_size) { perror("rand write"); close(fd); free(buf); return 4; } wcount++; clock_gettime(CLOCK_MONOTONIC, &now); } while (time_diff_sec(t1, now) < test_sec); clock_gettime(CLOCK_MONOTONIC, &t2); close(fd); double wsec = time_diff_sec(t1, t2); double wmb = (double)wcount * io_size / 1024 / 1024; printf("\nRANDOM WRITE:\n"); printf(" total : %.1f MB\n", wmb); printf(" time : %.3f sec\n", wsec); printf(" IOPS : %.0f ops/sec\n", wcount / wsec); printf(" BW : %.2f MB/s\n", wmb / wsec); fd = open(path, O_RDONLY | direct); if (fd < 0) { perror("open rand read"); free(buf); return 5; } clock_gettime(CLOCK_MONOTONIC, &t1); size_t rcount = 0; do { size_t blk = rand() % max_count; off_t offset = (off_t)blk * io_size; if (lseek(fd, offset, SEEK_SET) < 0) { perror("lseek rand read"); close(fd); free(buf); return 6; } ssize_t r = read(fd, buf, io_size); if (r < 0) { perror("rand read"); close(fd); free(buf); return 7; } rcount++; clock_gettime(CLOCK_MONOTONIC, &now); } while (time_diff_sec(t1, now) < test_sec); clock_gettime(CLOCK_MONOTONIC, &t2); close(fd); double rsec = time_diff_sec(t1, t2); double rmb = (double)rcount * io_size / 1024 / 1024; printf("\nRANDOM READ:\n"); printf(" total : %.1f MB\n", rmb); printf(" time : %.3f sec\n", rsec); printf(" IOPS : %.0f ops/sec\n", rcount / rsec); printf(" BW : %.2f MB/s\n", rmb / rsec); unlink(path); free(buf); return 0; } int main(int argc, char **argv) { char path[PATH_MAX]; make_path(path, sizeof(path), argc >= 2 ? argv[1] : NULL, "file.dat"); int rc = test_single_file_random_perf(path); return report_result("test_single_file_random_perf", rc); }