Linux I/O 块对齐的疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
pabno
V2EX    程序员

Linux I/O 块对齐的疑问

  •  
  •   pabno 2020-04-13 00:26:05 +08:00 3201 次点击
    这是一个创建于 2058 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    10 条回复    2020-04-13 11:25:19 +08:00
    Mirana
        1
    Mirana  
       2020-04-13 00:58:13 +08:00
    io 分为 buffer 写和非 buffer 写,由 open 的时候带的参数控制
    May725
        2
    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
        3
    kkk330  
       2020-04-13 01:47:36 +08:00 via iPhone
    前不久也刚看完这本书,应该是第 67 页的内容,我的理解是
    1. 在用户空间对齐可以避免内核再进行对齐操作,这也是标准 io 库有缓冲区的原因之一,而且按书中描述“避免内核内其他冗余操作”,暗示应该还有其他操作
    2. 在对齐的前提下,写入的 batch 比较大确实会减少系统调用,可以测试一下,但我记得越大效果越不明显
    neoblackcap
        4
    neoblackcap  
       2020-04-13 02:25:43 +08:00
    是的,是对页操作。但是如果每页都是 512B,然后 1130 完全不对齐的话,那么就是每次需要操作 3 页,页用完了就需要换页,这个换页成本就高了。
    vk42
        5
    vk42  
       2020-04-13 03:43:08 +08:00
    @May725 Linux 的 read 和 write 是 buffered I/O,除非文件是用 O_DIRECT 打开的

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

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

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

    不知道我这理解是否正确
    vk42
        9
    vk42  
       2020-04-13 10:52:01 +08:00
    @pabno 离开具体案例分析意义不大,可能的情况太多了,而且现实中还有文件系统在中间。看书学习的话先知道有个块对齐的情况就行了
    pabno
        10
    pabno  
    OP
       2020-04-13 11:25:19 +08:00
    @vk42 确实,如果 case 太多,很难理解完全,理解完全也不一定真的有指导意义,只是有点好奇这个问题
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3905 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 05:23 PVG 13:23 LAX 21:23 JFK 00:23
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86