我正在使用读/写来从本地磁盘常规文件中读取/写入。
我必须读取/写入少量数据。例如
read(fd, buf, 15)
write(fd, buf, 39);
有人告诉我,当有人检查我的拉取请求时,我应该避免读写少量数据。
他们说:例如,我应该分配一个大的内存(例如4k),首先将小数据复制到大内存中,然后一次写入大内存,而不是多次写入小数据。 而且我也应该一次读取4k数据,并将其存储到大内存中,然后我才能使用该大内存。
但是我知道当我写小数据时,我写到页面缓存(?),所以内核会照顾内存吗?当足够大时,内核将写入磁盘吗?
我明白吗?我应该避免读/写小数据吗?
答案 0 :(得分:4)
我明白吗?我应该避免读/写小数据吗?
您的想法正确,不,没有必要避免读取/写入小数据。
I / O子系统已经提供了BUFSIZ
字节的读取缓冲区(Linux上为8192字节,Windows上为512字节)(#define
在过去一年中在glibc中转移了,最初是派生的从_IO_BUFSIZE
,然后到_LIO_BUFSIZ
,现在是glibc源中的BUFSIZ
)
这是glibc提交从_IO_BUFSIZ
到普通BUFSIZ
Mechanically remove IO name aliases for types and constants (Wed, 7 Feb 2018).
因此,无论是读取一个字节或8192
字节(在Linux上)还是512
字节(在Windows上)都没有任何性能损失。第一次从以下位置请求数据时,I / O缓冲区已填充BUFSIZ
个字节(如果文件少于EOF
个字节,则填充到BUFSIZ
为止的字节数)文件。因此,您可以直接从内存中的读取缓冲区进行读取,并且小笔读取不会降低性能。
以类似的方式处理写入操作,直到写入缓冲区已满(或调用syncfs
或fsync
),才将其写入磁盘,从而导致所有缓冲的文件数据都写入底层文件系统
答案 1 :(得分:0)
读取/写入小尺寸数据是否有问题?
如果您只需要读取/写入少量数据,则读取/写入更多数据会浪费时间。
如果您需要读取/写入大量数据,则读取/写入许多小片段意味着您需要支付多次在用户空间和内核之间进行切换的开销(无论是由内核API调用还是由内核API调用引起的切换)由页面错误引起的切换)这是否有问题取决于情况-例如对于只打算执行3次的无关紧要的原型,但是对于在IO上花费大量时间的高性能生产软件,这是不希望的(尤其是现在Spectre和Meltdown缓解技术降低了切换成本,尤其是当没有其他原因,例如“代码维护”可以证明额外的开销是合理的。