Linux I/O 块对齐的疑问

2020-04-13 00:26:05 +08:00
 pabno

最近在看《 linux 系统编程》书的时候,有提到一个概念,就是 read/write 数据时,数据的大小最好与块大小对齐:比如块大小 1k,那么每次调用 read/write 的数据大小最好是 1k 的整数倍,这样会提高性能

里面提到了一个测试:针对 2m 的数据,每次写 1130 字节会比每次写 1024 字节表现更差,因为 1130 不是 1k 的倍数,即没有与块对齐

这里有个疑问: 每次 read/write 实际上都是针对页缓存操作的,后续由操作系统负责页回写到设备。那用户进程每次写的 batch 更大,不是意味着系统调用会更少,整体开销不是会更少吗?跟块设备进行交互的是块读取和块写入,而这个过程并不是发生在 read/write 的流程里的(不阻塞的意思),而是由内核处理, 那么块对齐的优势是体现在哪个方面?

还是说我哪个点理解有错?

2779 次点击
所在节点    程序员
10 条回复
Mirana
2020-04-13 00:58:13 +08:00
io 分为 buffer 写和非 buffer 写,由 open 的时候带的参数控制
May725
2020-04-13 00:59:28 +08:00
我的理解是这样的,
假如要读 5k 数据,块大小 1k,如果按照每次读 1k,只需要读 5 次即可完成,累计从磁盘读出 5k 的数据。
如果每次读 1.5k , 则要读 5/1.5 ,取整要读 4 次,由于是整块读,即 2k 读一次,至少累计从磁盘读出 7k 的数据。
5k < 7k,所以优势就出来了。
当然,这是基于 linux 的 read write 不带缓冲导致的,c 语言的 fread fwrie 这些是带缓冲的。

以上有问题的话,希望大佬指出哈。
kkk330
2020-04-13 01:47:36 +08:00
前不久也刚看完这本书,应该是第 67 页的内容,我的理解是
1. 在用户空间对齐可以避免内核再进行对齐操作,这也是标准 io 库有缓冲区的原因之一,而且按书中描述“避免内核内其他冗余操作”,暗示应该还有其他操作
2. 在对齐的前提下,写入的 batch 比较大确实会减少系统调用,可以测试一下,但我记得越大效果越不明显
neoblackcap
2020-04-13 02:25:43 +08:00
是的,是对页操作。但是如果每页都是 512B,然后 1130 完全不对齐的话,那么就是每次需要操作 3 页,页用完了就需要换页,这个换页成本就高了。
vk42
2020-04-13 03:43:08 +08:00
@May725 Linux 的 read 和 write 是 buffered I/O,除非文件是用 O_DIRECT 打开的

没看过书原文,从你介绍里面感觉书里的观点有点太死板了,实际应用可能有很多情况。不对齐可能有负面影响的例子很多,比如内核要做 padding,另外如果是 overwrite,写不满整页还要内核先把原有内容读出来等等
pabno
2020-04-13 09:53:39 +08:00
@May725 这里你可以理解有误,read/write 如果不指定 O_DIRECT 都话,都是带内核缓冲区的,fread/fwrite 是带了用户空间缓冲区
pabno
2020-04-13 09:54:07 +08:00
@Mirana 如果说是不经过 buffer 的,那倒是可以理解
pabno
2020-04-13 10:04:15 +08:00
@vk42 书中其实是有说明不指定 O_DIRECT 时,是带用内核缓冲区带。

我的疑问是,用户进程每次其实都是在跟内核缓冲区交互,比如我写入 1.5 页数据时,虽然多出的 0.5 页数据没有对齐,但是在页缓存有预读机制。可能在写这 0.5 页时,他对应的那一页数据已经预读到内核缓冲区中了,这时其实就是内存到内存的复制了,这种场景是否对齐已经不重要了?

另外如果系统页回写足够块,比如我写入 0.5 页数据后,页已经回写且淘汰了,我下次再写 0.5 页时,就要再一次读一页的数据到内核缓冲区并修改数据,然后页回写。这种场景页对齐就能减少开销。

不知道我这理解是否正确
vk42
2020-04-13 10:52:01 +08:00
@pabno 离开具体案例分析意义不大,可能的情况太多了,而且现实中还有文件系统在中间。看书学习的话先知道有个块对齐的情况就行了
pabno
2020-04-13 11:25:19 +08:00
@vk42 确实,如果 case 太多,很难理解完全,理解完全也不一定真的有指导意义,只是有点好奇这个问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/661791

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX