gpt4 book ai didi

c - Linux 上的 read() 和页面对齐缓冲区

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:39:01 24 4
gpt4 key购买 nike

我正在实现一个高效的文本文件加载器,并在这篇文章中从 GNU grep 的作者那里找到了一些很好的建议: http://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html

他建议的一件事是对页面对齐的数据 block 进行 read() 调用,将其放入页面对齐的缓冲区中。显然,这允许内核避免一些额外的缓冲。

我一直在寻找,但没有听到其他人支持这一说法。将 read() 调用到页面对齐缓冲区(可能使用 mmap/posix_memalign 等分配)实际上更有效吗?如果它不是真的,它曾经是真的吗?它是否在很大程度上取决于底层文件系统或其他类似因素?

谢谢!

最佳答案

通常,read() 会读入内核缓冲区,然后将其复制到用户空间。这个额外的副本就是正在讨论的内容。

Linux 支持通过 O_DIRECT 标志到 open() 的“直接 I/O”。这将跳过内核缓冲并直接读入用户空间缓冲区。但是,这种直接 I/O 需要对齐的访问和缓冲区。所以我认为那篇文章的作者并不是说当你对齐时魔法就会发生,而是说如果你仔细对齐,你可以使用“更接近金属”的技术来获得更多性能。

mmap() 是获得相同效果的更简单的方法。首次设置映射时,不会发生 I/O。当用户第一次访问映射中的页面时,将触发页面错误,内核通过分配用户页面并执行 I/O 来填充它来处理。没有副本。但同样,I/O 发生在页面大小的 block 中,在页面对齐的边界上。

这是否重要取决于内存复制相对于 I/O 发生的速度有多快,以及有多少 CPU 时间用于复制而不是做实际工作。例如,Web 服务器通常甚至不必查看它正在读取的内容:它只是将它再次写出一个套接字(这会产生另一个副本)。这就是为什么大量工作都进入了“零复制”技术,例如系统调用 sendfile()splice()。这些是专门的工作负载。通常,缓冲作用太小而无需担心。

关于c - Linux 上的 read() 和页面对齐缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18995107/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com