c++中的缓冲区大小

Buffer Size in C++

本文关键字:缓冲区 c++      更新时间:2023-10-16

我正在观察c++ Std库方法Std::ostream::write()的以下行为。

为了缓冲数据,我使用了下面的c++ API
std::ofstream::rdbuf()->pubsetbuf(char* s, streamsize n)

只要我们使用

在文件流上写入的数据大小(datasize)合适,就可以正常工作(使用strace实用程序进行验证)。
std::ofstream::write (const char* s, datasize n)

小于1023字节(低于此值时,写入将累积到缓冲区未满为止),但是当要写的数据大小超过1023字节时,将不考虑缓冲区,并将数据刷新到文件中。

。如果我将缓冲区大小设置为10KB,每次写入512bytes左右,strace将显示多个写入已合并为单个写入

writev(3, [{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 9728}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 512}], 2) = 10240 ( 10 KB )
writev(3, [{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 9728}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 512}], 2) = 10240
...

但是当我一次写入1024字节(保持缓冲区固定为10 KB)时,现在strace告诉我它没有使用缓冲区,并且每个ofstream::write调用都被转换为写系统调用。

writev(3, [{NULL, 0}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024}], 2) = 1024 ( 1KB )
writev(3, [{NULL, 0}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024}], 2) = 1024
...

是否有任何c++ API调用或Linux调优参数,我错过了?

这是libstdc++的实现细节,在bits/fstream.tcc的650行左右实现。基本上,如果写入大于2^10,它将跳过缓冲区。

如果你想知道这个决定背后的原因,我建议你发邮件给libstdc++开发列表。

http://gcc.gnu.org/ml/libstdc + +/

看起来某人在编写stdlib实现时没有给予足够的考虑就进行了"优化"。所以,你唯一的解决办法就是避免使用c++ API,而使用标准的C库。

这不是标准c++库的GNU/Linux实现中唯一的次优性:在我的机器上,malloc()比标准void* operator new (size_t size)快100个周期…