为什么不使用系统调用写文件.O_DIRECT标志使写文件变慢?



我有一小段名为test.go的代码。它计算两次写入时的时间(ns),将相同的字节片写入两个文件,一个带有syscall.O_DIRECT标志,另一个没有。

代码如下:

package main;
import (
"os"
"time"
"fmt"
"strconv"
"bytes"
"syscall"
// "os/exec"
)
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);
syscall.Write(fd1, writeContent);
if err != nil {panic(err);}
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);
syscall.Write(fd2, writeContent);
if err != nil {panic(err);}
t2= time.Now().UnixNano();
fmt.Println("sysW2:", t2-t1);
}

程序在linux命令行中运行如下:(用go build ./test.go编译后)

./test 1024

我期望用syscall.O_DIRECT标志写文件会更快,但结果表明,用syscall.O_DIRECT标志写文件大约是30比不写慢1倍:(

结果:

sysW1: 1107377
sysW2: 37155

为什么?我用系统调用学习写作。O_DIRECT做的复制更少,本来会更快,但现在却慢了很多。请帮我解释一下:(

PX:由于某些原因,在操场上运行程序时,结果总是0,因此我将不提供操场链接。

O_DIRECT不是你想的那样。虽然它做了更少的内存复制(因为它在复制到设备驱动程序之前不会复制到缓存),但这并没有给你带来性能提升。

文件系统缓存确保系统调用可以在数据写入设备之前尽早返回,并缓冲数据以更大的块发送数据。

对于O_DIRECT,系统调用等待,直到数据完全传输到设备。

open调用的手册页:

O_DIRECT(自Linux 2.4.10起)

尽量减少I/O对缓存的影响文件。通常这会降低性能,但事实确实如此在特殊情况下很有用,比如应用程序它们自己的缓存。文件I/O是直接从/到文件的用户空间缓冲区。O_DIRECT标志本身就是一个努力同步传输数据,但没有给出O_SYNC标志保证数据是必需的元数据被传输。

参见:O_DIRECT的真正含义是什么?

您不需要在使用缓存后手动释放缓存。Linux内核认为缓存是空闲的可用内存。如果进程需要的内存被缓存占用,内核将在此时刷新/释放缓存。缓存没有"用完"。记忆。

相关内容

  • 没有找到相关文章

最新更新