区块链技术博客
www.b2bchain.cn

寻求解释/信息:Windows使用“ fsync”(FlushFileBuffers)写入I / O性能 – c#程序员分享

本文介绍了寻求解释/信息:Windows使用“ fsync”(FlushFileBuffers)写入I / O性能 – c#程序员分享,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

这个问题是我之前发布的一个问题的后续内容:Windows fsync (FlushFileBuffers) performance with large files。在哪里找到了可能的解决方案,但又提出了新的问题。

在对fsync写入的不同场景进行基准测试时,我发现了许多令人惊讶的结果。我希望有人能帮助您解释或指出解释这些结果的信息方向。

该基准测试的工作是将8个页面(32 K)的批处理顺序随机地(大小为4096字节的大页面)写入文件,然后刷新写入。它总共写入200000页,总计800 MB和25000次刷新。在开始写入之前,文件的大小被设置为其最终长度。

它总共支持4个选项,其中所有组合都可以运行:

在写入批处理或常规刷新(NS)之后执行“ fsync” / FlushFileBuffers操作(FS)。
在开始写入(LB)或将文件留空(E)之前将单个字节写入文件的最后位置。
要使用普通的缓冲写入(B)或无缓冲/直写(WT)写入(使用FILE_FLAG_NO_BUFFERING和FILE_FLAG_WRITE_THROUGH)。
要直接写入文件流,即通过文件句柄(F)或使用内存映射(MM)间接写入文件。

下表总结了我在系统(带有慢速主轴磁盘的64位Win 7笔记本电脑)上对这些选项的所有组合的发现。

我发现,“ fsynced”缓冲写入的性能随着文件大小的增加呈指数下降,从而导致吞吐量难以置信地低,这使得在与大文件结合使用时不可行。如果文件的最后一个字节被写入(选项LB),则吞吐量甚至会更低,因此我担心在随机而不是顺序写入的情况下,性能会更加出色。

但是令人惊讶的是,使用无缓冲/直写式I / O时,吞吐量保持恒定,与文件大小无关。最初(前100-200 MB),其吞吐量低于缓冲写入,但此后,平均吞吐量迅速赶上,并且完成写入800 MB的速度大大提高。更令人惊讶的是,如果文件的最后一个字节被写入,那么吞吐量将增加2倍。

通过内存映射文件写入文件时,在使用无缓冲/直写标志打开文件的情况下,也会看到同样的性能下降。同样,如果文件的最后一个位置写入了一个字节,性能也会变差。

更新
根据Howard的解释here和here,我在开始写操作(即打开现有的,完全写好的文件并覆盖它)之前重新运行了测试,而没有创建新文件。我已经更新了原始问题中的代码,以反映对此测试所做的更改。结果部分与他在Linux上的解释和发现相符。但是有一些值得注意的例外。下表提供了结果,红色突出显示了重大变化,蓝色突出显示了未发生变化的地方,这是令人惊讶的(即,如果霍华德解释中提到的影响是唯一起作用的,则与预期不符)。

对于使用“ fsync”刷新进行缓冲的文件写入(即不通过memmap),现在性能已从指数衰减变为恒定趋势。但是,与以前的测试方案相比,现在所需的时间要长得多。吞吐率恒定为1.5 MB / s,在此之前,吞吐率以20 MB / s的速度开始呈指数下降至1.5 MB / s。似乎可能的解释是,每次刷新时文件元数据也会被刷新,从而导致磁盘旋转以寻找元数据的位置。

对于“直写”到文件方案,写入最后一个字节或不写入最后一个字节的结果现在相同,这与霍华德的解释所期望的一致。

但是,除了一个值得注意的例外,对内存映射的写入实际上并没有改变,这令人惊讶。它们在写入性能上仍然显示相同的指数衰减(从大约20 MB / s开始下降到1.8 MB / s)。这表明正在发挥一种不同的机制。一个值得注意的例外是如果创建的基础文件没有FILE_FLAG_WRITE_THROUGH并且执行了“ fsync”刷新。现在,此方案显示了稳定的(较差)性能,吞吐量约为1.6 MB / s。由于我有一些疑问,因此我多次重试了此方案,每次都给出相同的结果。

为了进一步了解,我还使用一个较小的文件(50000页,总计200 MB)重新运行了该测试,以确认fsync性能(用于缓冲I / O)实际上取决于文件大小。结果如下所示,需要特别注意的结果以红色突出显示。

这些结果与较大文件的相关性很好。值得注意的变化是,对于突出显示的那些写入,其写入性能似乎更高,在那里,它们似乎达到了约7 MB / s的限制。

根据到目前为止对我的系统的观察,总结为高度推测性的结论:

具有已缓冲IO(即没有FILE_FLAG_WRITE_THROUGH标志)的文件在Windows上的“ fsync”性能随着已写入文件的字节数呈指数下降。原因似乎是每次都需要刷新文件元数据,这会导致磁盘搜索到文件的开头。
当写入内存映射文件时,Windows上的“ fsync”性能也显示出呈指数级下降的性能。我目前还没有引起这种情况的确切机制的解释。

鉴于这种观察到的性能,至少对于我的用例而言,这两个I / O选项不会代表可行的解决方案。

按照Greg's suggestion,我将在Windows磁盘缓存关闭的情况下重新运行测试,并且还将运行Howard提供的benchmark code,以排除由于我自己的错误而导致结果出现偏差的可能性。

更新2
我已经完成测试,目前正在汇总结果。为了不写“的完整历史”,我将用结果摘要,发现和一些结论来代替当前问题的内容。霍华德(Howard)关于这个问题的答案以及在.NET代码旁边运行他的c基准代码的能力非常有用。这些结果与应用程序相关性很好。 Rlb的回答使我对与磁盘相关的“合理数字”有了更好的了解。谢谢。

问题的一部分仍然没有答案。尤其与在写入内存映射时观察到的性能下降(取决于文件大小)有关。它可能与搜寻/元数据刷新有关,但我尚不清楚原因/方式。

参考方案

您会看到同步运行的速度呈指数级下降,因为您相信这些并不是纯粹的顺序工作负载。由于每次都从一个新文件开始,因此您的写入使文件不断增长,并且元数据需要在文件系统中进行更新。这需要多次查找,并且随着文件的增长,从文件末尾到元数据的查找将花费越来越长的时间。我还错误地将此问题发布在您的其他问题上,请参阅此处的完整答案:https://stackoverflow.com/a/18429712/894520

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 寻求解释/信息:Windows使用“ fsync”(FlushFileBuffers)写入I / O性能 – c#程序员分享
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们