【问题标题】:How does the size of memory region argument in read() and write() affect the IO performance?read() 和 write() 中的内存区域参数大小如何影响 IO 性能?
【发布时间】:2019-05-28 14:50:47
【问题描述】:

an IO example from Advanced Programming in Unix Environment

#include "apue.h"
#define BUFFSIZE 4096
int
main(void)
{
    int  n;
    char  buf[BUFFSIZE];
    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
    if (write(STDOUT_FILENO, buf, n) != n)
    err_sys("write error");
    if (n < 0)
    err_sys("read error");
    exit(0);
}

所有普通的 UNIX 系统 shell 都提供了一种打开文件进行读取的方法 在标准输入上创建(或重写)文件 标准输出,并允许用户利用 shell 的 I/O 重定向工具。

图 3.6 显示了读取 516,581,760 字节的结果 文件,使用 20 种不同的缓冲区大小,具有标准输出 重定向到 /dev/null。本次测试使用的文件系统是 具有 4,096 字节块的 Linux ext4 文件系统。 (st_blksize 值是 4,096。)这占系统时间的最小值 发生在几个定时测量周围开始 BUFFSIZE 为 4,096。将缓冲区大小增加到超出此限制已 积极作用不大。

  1. BUFFSIZE 如何影响读取文件的性能?

    BUFFSIZE 增加到 4096,为什么性能 提升?随着BUFFSIZE 增加到 4096 以上,为什么 性能没有明显提升?

  2. 内核缓冲区(不是buf,大小为BUFFSIZE 程序)对性能的帮助,与BUFFSIZE相关?

    BUFFSIZE 较小时,内核缓冲区是否有助于积累 小写,所以要提高性能?

【问题讨论】:

  • 嗨蒂姆。我们试图减少此处帖子上的闲聊材料,特别感谢,请帮助我,非常感谢等。有a canonical reference on Meta。我通常不会针对次要项目提及它,但您有 872 个,所以我假设您不知道链接的帖子。这里倾向于简洁的文档风格。

标签: c linux io


【解决方案1】:

read()write() 的每次调用都需要一个系统调用(与内核通信),以及将实际复制到(或从)内核内存空间的时间。

系统调用本身会产生固定的(每次调用)开销/成本,而复制数据的成本当然与要复制的数据量成正比。

因此,如果你read()/write()的缓冲区非常小,那么进行系统调用的开销与复制的数据字节数相比会比较高;而且由于您必须进行大量调用,因此总体运行时间将比您进行大量传输时更长。

调用read()/write() 的次数越少,缓冲区越大,系统就可以将系统调用的开销分摊到每次调用更多的字节数上,从而避免效率低下。然而,在某些时候,随着大小变大,系统调用开销变得完全可以忽略不计,此时程序的效率完全取决于传输数据的成本,而这取决于硬件的速度。这就是为什么您会看到随着尺寸变大而性能趋于平稳。

read()write() 不会将小写操作累积在一起,因为它们代表直接的系统调用。如果您希望以这种方式缓冲小型读取/写入,C 运行时提供 fread()fwrite() 包装器,它们将在您的进程空间内为您完成此操作。

【讨论】:

  • 谢谢。 (1) 为什么文件系统的块大小是 4,096 字节的调平大小? (2) "read() 和 write() 不会一起累积小写入,因为它们代表直接的系统调用。如果您希望以这种方式缓冲小读取/写入,C 运行时提供 fread() 和 fwrite() 包装器这将在你的进程空间内为你做到这一点。”我的意思是内核级缓冲区,而不是我帖子中的用户空间缓冲区。
  • 对于(1),我不知道——也许是巧合,也许是有原因的。对于 (2),文件系统(和/或硬盘驱动器的内部硬件)会进行额外的缓冲;特别是,write() 几乎总是会在位实际到达物理磁盘之前返回;但是,这种缓冲并不能解决系统调用开销问题,因为每次调用 write() 都会调用一个系统调用,因此无论之后发生什么,都会调用一个系统调用的 CPU 周期。
  • 每次读/写传输的数据小于文件系统的块大小时,是否比每次读/写传输的数据大于文件系统的块大小时传输的块更多?跨度>
猜你喜欢
  • 2019-04-03
  • 1970-01-01
  • 1970-01-01
  • 2016-03-09
  • 2013-10-05
  • 2012-05-20
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
相关资源
最近更新 更多