zvfs: 随机写测试
This commit is contained in:
100
README.md
100
README.md
@@ -35,6 +35,8 @@ zvfs的测试结果:
|
||||
1. 大块4K:1460MiB/s
|
||||
2. 小块128K:1266MiB/s
|
||||
|
||||
非对齐情况下,写入性能/2,因为需要read-update-write。
|
||||
|
||||
### spdk_nvme_perf 性能基准测试
|
||||
```shell
|
||||
cd /home/lian/share/10.1-spdk/spdk
|
||||
@@ -164,6 +166,55 @@ READ:
|
||||
=== 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 小块
|
||||
```shell
|
||||
root@ubuntu:/home/lian/share/10.1-spdk/zvfs# ./func_test
|
||||
@@ -288,6 +339,55 @@ READ:
|
||||
=== 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
|
||||
1. blob_store: blob仓库,管理多个blob对象。
|
||||
2. blob: 存储对象,逻辑上连续,物理上不一定连续。相当于文件。
|
||||
|
||||
236
zvfs/func_test.c
236
zvfs/func_test.c
@@ -102,6 +102,238 @@ static int test_single_file_perf(const char *path)
|
||||
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: 原有基础测试 */
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -402,7 +634,9 @@ int main(int argc, char **argv)
|
||||
// rc |= test_lseek(path);
|
||||
// rc |= test_dual_open_same_file(path);
|
||||
// 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");
|
||||
|
||||
Reference in New Issue
Block a user