c# – 寻求的解释/信息:Windows使用“fsync”写入I / O性能(Flu
这个问题是我发布的早期问题的后续跟进:
Windows fsync (FlushFileBuffers) performance with large files.我找到了一个可能的解决方案,但也提出了新的问题.
在针对fsynced写入的不同场景进行基准测试时,我发现了许多令人惊讶的结果.我希望有人可以帮助解释或指出我解释这些结果的信息方向. 这个基准测试的作用是将8个(32 K)批量的随机块(大4096字节)顺序写入文件,然后刷新写入.它总共写了200000页,总计800 MB和25000次刷新.在开始写入之前,文件的大小设置为其最终长度. 它支持总共4个选项,其中运行所有组合: >在写入批处理或正常刷新(NS)后执行“fsync”/ FlushFileBuffers操作(FS). 下表总结了我对我的系统(具有慢速主轴磁盘的64位Win 7笔记本电脑)的所有这些选项组合的发现. 我发现“fsynced”缓冲写入的性能随着文件大小呈指数级下降到令人难以置信的低吞吐量,这使得与大文件组合使用时不可行.如果文件的最后一个字节写入(选项LB),吞吐量甚至更低,所以我担心在随机而不是顺序写入情况下,性能将更加显着. 然而令人惊讶的是,对于无缓冲/写入I / O,吞吐量保持不变,与文件大小无关.最初(前100-200 MB)它的吞吐量低于缓冲写入,但之后平均吞吐量迅速赶上,并且完成写入800 MB的速度更快.更令人惊讶的是,如果文件的最后一个字节写入,吞吐量会增加2倍. 通过内存映射文件写入文件时,在使用无缓冲/写入标志打开文件的情况下,可以看到性能相同的指数下降.在这里,如果文件有一个字节写入其最后位置,性能会更差. UPDATE 对于具有“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”性能随着已写入文件的字节数呈指数级递减.原因似乎是每次都需要刷新文件元数据,这会导致磁盘搜索到文件的开头. 鉴于这种观察到的性能,至少在我的用例中,这两个I / O选项并不代表可行的解决方案. 根据Greg’s suggestion,我将在关闭Windows磁盘缓存的情况下重新运行测试,并且我还将运行Howard提供的benchmark code,以排除由于我自己的错误而导致结果偏差的可能性. 更新2 问题的一部分仍未得到答复.特别与在写入存储器映射时观察到的降低(和依赖于文件大小)性能有关.它可能与搜索/元数据刷新有关,但我还不清楚为什么/如何. 解决方法
您看到同步运行的速度呈指数级下降,因为这些并不是您认为的纯顺序工作负载.由于每次都是以新文件开头,因此您的写入会增加文件,并且需要在文件系统中更新元数据.这需要多次搜索,随着文件的增长,从文件末尾到元数据的搜索需要越来越长的时间.我也错误地在你的另一个问题上发布了这个,请看那里的完整答案:
https://stackoverflow.com/a/18429712/894520
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |