我有一个测试程序。在Linux内核3.1。*上大约需要37秒,但在内核3.0.18上只需要大约1秒钟(我只需要在同一台机器上替换内核)。请给我一个如何在内核3.1上改进它的线索。谢谢!
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int my_fsync(int fd)
{
// return fdatasync(fd);
return fsync(fd);
}
int main(int argc, char **argv)
{
int rc = 0;
int count;
int i;
char oldpath[1024];
char newpath[1024];
char *writebuffer = calloc(1024, 1);
snprintf(oldpath, sizeof(oldpath), "./%s", "foo");
snprintf(newpath, sizeof(newpath), "./%s", "foo.new");
for (count = 0; count < 1000; ++count) {
int fd = open(newpath, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU);
if (fd == -1) {
fprintf(stderr, "open error! path: %s\n", newpath);
exit(1);
}
for (i = 0; i < 10; i++) {
rc = write(fd, writebuffer, 1024);
if (rc != 1024) {
fprintf(stderr, "underwrite!\n");
exit(1);
}
}
if (my_fsync(fd)) {
perror("fsync failed!\n");
exit(1);
}
if (close(fd)) {
perror("close failed!\n");
exit(1);
}
if (rename(newpath, oldpath)) {
perror("rename failed!\n");
exit(1);
}
}
return 0;
}
# strace -c ./testfsync
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
98.58 0.068004 68 1000 fsync
0.84 0.000577 0 10001 write
0.40 0.000275 0 1000 rename
0.19 0.000129 0 1003 open
0.00 0.000000 0 1 read
0.00 0.000000 0 1003 close
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 1 access
0.00 0.000000 0 3 brk
0.00 0.000000 0 1 munmap
0.00 0.000000 0 2 setitimer
0.00 0.000000 0 68 sigreturn
0.00 0.000000 0 1 uname
0.00 0.000000 0 1 mprotect
0.00 0.000000 0 2 writev
0.00 0.000000 0 2 rt_sigaction
0.00 0.000000 0 6 mmap2
0.00 0.000000 0 2 fstat64
0.00 0.000000 0 1 set_thread_area
------ ----------- ----------- --------- --------- ----------------
100.00 0.068985 14099 1 total
答案 0 :(得分:8)
内核3.1。*实际上正在进行同步,3.0.18正在伪造它。您的代码执行1,000次同步写入。由于您截断了文件,因此每次写入也会放大文件。所以你实际上有2000次写操作。典型的硬盘驱动器写入延迟大约为每个I / O 20毫秒。所以2,000 * 20 = 40,000毫秒或40秒。所以看起来是对的,假设你正在写一个典型的硬盘。
基本上,通过在每次写入后进行同步,您可以使内核无法有效地缓存或重叠写入,并强制执行每个操作的最坏情况行为。此外,硬盘驱动器必须在写入数据的位置和每次写入时元数据写入的位置之间来回搜索。
答案 1 :(得分:2)