You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go中使用syscall.O_DIRECT标志写文件为何速度更慢?

O_DIRECT写入性能不符合预期问题

我编写了一段名为test.go的测试代码,用于统计两次写入操作的耗时(单位:纳秒):两次操作分别向文件写入相同的字节切片,其中一次打开文件时携带syscall.O_DIRECT标志,另一次不携带该标志。

测试代码如下:

package main

import (
        "os"
        "time"
        "fmt"
        "strconv"
        "bytes"
        "syscall"
)
func main() {
        num, _ := strconv.Atoi(os.Args[1]);
        writeContent:= bytes.Repeat( []byte("1"), num );
        t1:= time.Now().UnixNano();
        fd1, err := syscall.Open("abc.txt", syscall.O_WRONLY | syscall.O_DIRECT | syscall.O_TRUNC, 0);
        if err != nil {panic(err);}
        syscall.Write(fd1, writeContent);
        t2:= time.Now().UnixNano();
        fmt.Println("sysW1:", t2-t1);

        t1= time.Now().UnixNano();
        fd2, err := syscall.Open("abc.txt", syscall.O_WRONLY | syscall.O_TRUNC, 0);
        if err != nil {panic(err);}
        syscall.Write(fd2, writeContent);
        t2= time.Now().UnixNano();
        fmt.Println("sysW2:", t2-t1);
}

代码通过go build ./test.go编译后,在Linux命令行执行如下命令运行:

./test 1024

测试预期携带syscall.O_DIRECT标志的写入速度更快,但实际结果显示携带该标志的写入速度比不携带的慢约30倍,输出如下:

sysW1: 1107377
sysW2: 37155

此前认知中syscall.O_DIRECT模式下数据拷贝次数更少,写入速度应当更快,实际结果与预期相反。

注:因在Go Playground中运行该程序时输出结果始终为0,故不提供在线运行链接。

原因解释
  • 两组测试的计时维度完全不一致:不带O_DIRECT的常规写入是缓存异步写入,系统调用只要把数据从用户空间拷贝到内核页缓存就会立刻返回,不会等待数据真正写入物理存储,测得的37155纳秒本质是内存拷贝的开销,实际磁盘IO会在调用返回后由内核异步调度执行。而O_DIRECT的核心语义就是绕过内核页缓存,IO请求会直接下发到块设备,write()调用会阻塞到整个物理写入流程完成才返回,磁盘写入的延迟本来就比内存操作高2~3个数量级,耗时更长是必然结果。
  • O_DIRECT存在严格的对齐约束:Linux系统下使用O_DIRECT发起IO必须同时满足三个对齐要求:用户态缓冲区的内存起始地址、文件写入偏移、写入数据长度,三者都必须是块设备逻辑块大小(传统机械硬盘为512B,新型4Kn盘为4096B)的整数倍。测试代码里用bytes.Repeat生成的缓冲区没有做专门的内存对齐,内核处理IO时会额外申请一块符合对齐要求的临时缓冲区做数据拷贝,反而比普通写入多了一次内存拷贝开销。
  • 测试场景完全不匹配O_DIRECT的适用范围:O_DIRECT是为数据库、分布式存储这类自行实现用户态缓存、需要大块顺序写入、希望避免页缓存双重缓存开销的场景设计的,小数据量写入场景下不会带来任何收益。测试仅写入1KB的极小数据,绕过缓存带来的收益完全覆盖不了块设备单次IO的寻址、传输开销,加上两次写入操作同一个文件,第一次O_DIRECT写入后文件元数据已经进入系统缓存,第二次普通写入的打开、写入流程天然更快,结果偏差会进一步放大。
  • 若要做公平的性能对比,常规写入组需要在写完后调用fsync确保数据真正落盘之后再停止计时,否则两组测试统计的根本不是同一个阶段的耗时,结果没有参考价值。

内容的提问来源于stack exchange,提问作者Aluminate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:27:20