`O_DIRECT | 有什么区别? O_SYNC` + write() 和 `O_DIRECT` + write() + fsync()

问题描述

我想知道两者的区别

    char *text = (char *)malloc(4096);
    memset(text,'a',4096);

    int fd = open(filepath,O_RDWR | O_CREAT | O_DIRECT);

    for(int i=0; i<1000; i++) {
        write(fd,(void *)text,4096);
        fsync(fd);
    }

    close (fd);

    char *text = (char *)malloc(4096);
    memset(text,O_RDWR | O_CREAT | O_DIRECT | O_SYNC); //<----Difference

    for(int i=0; i<1000; i++) {
        write(fd,4096);
        // fsync(fd);  <--------------------------------------------------Difference
    }

    close (fd);

上面代码性能比下面的慢很多。

解决方法

一方面应该没有任何区别,因为在两种情况下都必须发生相似的工作量(假设没有诡计,先写然后磁盘刷新)。另一方面,第一种情况必须执行两倍的系统调用,因此(理论上)有更多开销(特别是如果进行系统调用所需的时间占执行操作所需的总时间的很大一部分)。很可能它可能取决于磁盘/内核/CPU/I/O 的大小等。关于两者之间是否存在差异以及哪个更快。也许在第二种情况下,内核可以发送带有 FUA 位设置的写入,这意味着差异可能取决于您打开的文件/设备(因为这可以控制是否可以完成此类优化)...

使用 O_SYNC 还会使 write() 调用返回时出现错误,但正如其他评论中所述,您没有检查返回代码...