从下面看,16M 的 I/O 做得不好,只有一次,是 >20ms。这几乎是完全可以感知的。
要点:
- I/O 值得关注,因为
- 做很多事情都会导致严重的延误。
- 512 字节的写入很痛苦。
- 4096 字节写入不会。
内存或磁盘上的偏移量并不重要,所以calloc'ing 任何应该做的都很好(你可以试试)。
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
int main(int c, char **v)
{
int wsiz = c>1 ? atoi(*++v) : 512;
int seek = c>2 ? atoi(*++v) : 0;
int woff = c>3 ? atoi(*++v) : 0;
int fsiz = c>4 ? atoi(*++v) : 16 * 1024 * 1024;
int reps = c>5 ? atoi(*++v) : 1000;
printf("writesize %d, seek %d, align %d, filesize %d, reps %d\n",
wsiz, seek, woff, fsiz, reps);
if (wsiz<=0|seek<0|woff<0|fsiz<wsiz)
return 1;
int fd = open("data", O_CREAT | O_RDWR, 0700);
char *data = mmap(0, 2*wsiz, PROT_READ, MAP_ANON | MAP_PRIVATE, 0, 0);
for (int t = reps; t--; lseek(fd, seek, 0))
for (int c = fsiz / wsiz; c--;)
if (write(fd, data+woff, wsiz) != wsiz)
perror("write?"), abort();
return close(fd);
}
cc -o bin/wipetest -g -O --std=c11 -march=native -pipe -Wall -Wno-parentheses wipetest.c
------------------------------------------------------
writesize 512, seek 0, align 0, filesize 16777216, reps 1000
real 0m20.727s
user 0m0.513s
sys 0m20.220s
------------------------------------------------------
writesize 4096, seek 0, align 0, filesize 16777216, reps 1000
real 0m3.889s
user 0m0.077s
sys 0m3.687s
------------------------------------------------------
writesize 16777216, seek 0, align 0, filesize 16777216, reps 1000
real 0m3.205s
user 0m0.000s
sys 0m3.203s
------------------------------------------------------
writesize 512, seek 500, align 0, filesize 16777216, reps 1000
real 0m23.829s
user 0m0.463s
sys 0m23.247s
------------------------------------------------------
writesize 4096, seek 500, align 0, filesize 16777216, reps 1000
real 0m5.531s
user 0m0.053s
sys 0m5.480s
------------------------------------------------------
writesize 16777216, seek 500, align 0, filesize 16777216, reps 1000
real 0m3.435s
user 0m0.000s
sys 0m3.433s
------------------------------------------------------
writesize 512, seek 0, align 12, filesize 16777216, reps 1000
real 0m21.478s
user 0m0.537s
sys 0m20.820s
------------------------------------------------------
writesize 4096, seek 0, align 12, filesize 16777216, reps 1000
real 0m3.722s
user 0m0.057s
sys 0m3.667s
------------------------------------------------------
writesize 16777216, seek 0, align 12, filesize 16777216, reps 1000
real 0m3.232s
user 0m0.000s
sys 0m3.233s
------------------------------------------------------
writesize 512, seek 500, align 12, filesize 16777216, reps 1000
real 0m23.775s
user 0m0.550s
sys 0m23.113s
------------------------------------------------------
writesize 4096, seek 500, align 12, filesize 16777216, reps 1000
real 0m5.566s
user 0m0.050s
sys 0m5.517s
------------------------------------------------------
writesize 16777216, seek 500, align 12, filesize 16777216, reps 1000
real 0m3.277s
user 0m0.000s
sys 0m3.277s