zvfs: 随机写测试

This commit is contained in:
2026-02-25 04:56:51 +00:00
parent d6a9e673a1
commit 4f3e2a592f
2 changed files with 335 additions and 1 deletions

100
README.md
View File

@@ -35,6 +35,8 @@ zvfs的测试结果
1. 大块4K1460MiB/s 1. 大块4K1460MiB/s
2. 小块128K1266MiB/s 2. 小块128K1266MiB/s
非对齐情况下,写入性能/2因为需要read-update-write。
### spdk_nvme_perf 性能基准测试 ### spdk_nvme_perf 性能基准测试
```shell ```shell
cd /home/lian/share/10.1-spdk/spdk cd /home/lian/share/10.1-spdk/spdk
@@ -164,6 +166,55 @@ READ:
=== all tests PASSED === === all tests PASSED ===
``` ```
#### no O_DIRECT 随机 对齐 大块
```shell
root@ubuntu:/home/lian/share/10.1-spdk/zvfs/zvfs# ./func_test
=== test_single_file_random_perf ===
Path : /tmp/test.dat
IO size : 128 KB
Range : 2048 MB
Duration: 10 sec
RANDOM WRITE:
total : 8930.8 MB
time : 10.001 sec
IOPS : 7144 ops/sec
BW : 893.01 MB/s
RANDOM READ:
total : 8238.9 MB
time : 10.000 sec
IOPS : 6591 ops/sec
BW : 823.89 MB/s
=== all tests PASSED ===
```
#### no O_DIRECT 随机 非对齐 大块
```shell
root@ubuntu:/home/lian/share/10.1-spdk/zvfs/zvfs# ./func_test
=== test_single_file_random_perf ===
Path : /tmp/test.dat
IO size : 128 KB
Range : 2048 MB
Duration: 10 sec
RANDOM WRITE:
total : 5964.4 MB
time : 10.000 sec
IOPS : 4771 ops/sec
BW : 596.43 MB/s
RANDOM READ:
total : 6607.8 MB
time : 10.000 sec
IOPS : 5286 ops/sec
BW : 660.77 MB/s
=== all tests PASSED ===
```
#### O_DIRECT 小块 #### O_DIRECT 小块
```shell ```shell
root@ubuntu:/home/lian/share/10.1-spdk/zvfs# ./func_test root@ubuntu:/home/lian/share/10.1-spdk/zvfs# ./func_test
@@ -288,6 +339,55 @@ READ:
=== all tests PASSED === === all tests PASSED ===
``` ```
#### 对齐随机写(大块)
```shell
root@ubuntu:/home/lian/share/10.1-spdk/zvfs/zvfs# LD_PRELOAD=./libzvfs.so ./func_test /zvfs
=== test_single_file_random_perf ===
Path : /zvfs/file.dat
IO size : 128 KB
Range : 2048 MB
Duration: 10 sec
RANDOM WRITE:
total : 17461.8 MB
time : 10.000 sec
IOPS : 13969 ops/sec
BW : 1746.17 MB/s
RANDOM READ:
total : 17439.5 MB
time : 10.000 sec
IOPS : 13952 ops/sec
BW : 1743.95 MB/s
=== all tests PASSED ===
```
#### 非对齐随机写(大块)
```shell
root@ubuntu:/home/lian/share/10.1-spdk/zvfs/zvfs# LD_PRELOAD=./libzvfs.so ./func_test /zvfs
=== test_single_file_random_perf ===
Path : /zvfs/file.dat
IO size : 128 KB
Range : 2048 MB
Duration: 10 sec
RANDOM WRITE:
total : 7500.2 MB
time : 10.000 sec
IOPS : 6000 ops/sec
BW : 750.02 MB/s
RANDOM READ:
total : 15143.8 MB
time : 10.000 sec
IOPS : 12115 ops/sec
BW : 1514.35 MB/s
=== all tests PASSED ===
```
## SPDK ## SPDK
1. blob_store: blob仓库管理多个blob对象。 1. blob_store: blob仓库管理多个blob对象。
2. blob: 存储对象,逻辑上连续,物理上不一定连续。相当于文件。 2. blob: 存储对象,逻辑上连续,物理上不一定连续。相当于文件。

View File

@@ -102,6 +102,238 @@ static int test_single_file_perf(const char *path)
return 0; return 0;
} }
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);
/* ================= RANDOM WRITE ================= */
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);
/* ================= RANDOM READ ================= */
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;
}
static int test_single_file_random_noaligned_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);
/* ================= RANDOM WRITE ================= */
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 {
off_t offset = (off_t)(rand() % (max_size - 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);
/* ================= RANDOM READ ================= */
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 {
off_t offset = (off_t)(rand() % (max_size - 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;
}
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Test 1: 原有基础测试 */ /* Test 1: 原有基础测试 */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
@@ -402,7 +634,9 @@ int main(int argc, char **argv)
// rc |= test_lseek(path); // rc |= test_lseek(path);
// rc |= test_dual_open_same_file(path); // rc |= test_dual_open_same_file(path);
// rc |= test_two_files(path_a, path_b); // rc |= test_two_files(path_a, path_b);
rc |= test_single_file_perf(path); // rc |= test_single_file_perf(path);
// rc |= test_single_file_random_perf(path);
rc |= test_single_file_random_noaligned_perf(path);
printf("\n=== all tests %s ===\n", rc == 0 ? "PASSED" : "FAILED"); printf("\n=== all tests %s ===\n", rc == 0 ? "PASSED" : "FAILED");