在C ++中的缓冲区大小

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

为了缓冲我使用以下C ++ API的数据

std::ofstream::rdbuf()->pubsetbuf(char* s, streamsize n) 

这工作正常(使用strace实用程序进行validation),只要我们在文件stream上使用的数据大小(数据大小)

 std::ofstream::write (const char* s, datasize n) 

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

例如,如果我将缓冲区大小设置为10KB,并且每次写入大约512字节,则strace将显示多个写入已合并为单个写入

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

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

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

是否有任何C ++ API调用或Linux调优参数,我缺less?

这是libstdc ++的实现细节,围绕位/ 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个循环。