我正在观察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 ++开发列表。
看起来有人写stdlib实现做了一个“优化”,没有给予足够的思想。 所以,唯一的解决方法是避免使用C ++ API并使用标准的C库。
在标准C ++库的GNU / Linux实现中,这不是唯一次优化:在我的机器上, malloc()
比标准void* operator new (size_t size)
快100个循环。