如何监控程序的IO

时间:2015-04-16 19:35:47

标签: c++ linux io ofstream

用c ++编写的这个开源科学应用程序往往会在很短的时间内产生大量的小写(使用ofstream)。我正在修改代码,以便IO不会那么频繁。

它实际上只打开/写入一个或两个文件。在程序运行时监控IO频率的最佳方法是什么?或者可能要监控某些文件的写入频率?

编辑: 在我改变了所有" endl" to" \ n",strace显示该程序正在做很多" writev"相反"写"原始代码。这是strace输出比较。

在:

write(4, "+\n", 2)                      = 2
write(4, ">>=@ABCEDBCFBEACDDCDDCBBCCDDCFAC"..., 77) = 77
write(3, "@C3A7DACXX140502:1:1314:6663:801"..., 37) = 37
write(3, "CATCAAACAAGATATGGATGTAGAACGCTCAG"..., 77) = 77
write(3, "+\n", 2)                      = 2
write(3, "?@>CCCDEDDFBDBCECCCEBAECCD@DDEDE"..., 77) = 77
write(4, "@C3A7DACXX140502:1:1314:6663:801"..., 37) = 37
write(4, "TTAGACAATGTAGTGAAATAGTTACTTTGGGG"..., 77) = 77
write(4, "+\n", 2)                      = 2
write(4, "==:BABBCDFBCEBECABBBE@B?DCDBDDCC"..., 77) = 77
write(3, "@C3A7DACXX140502:1:1314:6664:692"..., 36) = 36
write(3, "CAAAGACAGGTATGGAGACAGGAGAAGGGAGC"..., 77) = 77
write(3, "+\n", 2)                      = 2
write(3, ";=;3=6.?A'7*:;@AA=@@?C>.++68>),)"..., 77) = 77
write(4, "@C3A7DACXX140502:1:1314:6664:692"..., 36) = 36
write(4, "ACAAGATGTCTTCGGAGTTTCCGGGATAGCCA"..., 77) = 77

后:

writev(3, [{"\n@C3A7DACXX140502:3:1209:20544:1"..., 8186}, {"ACCTCCTCCTGCTTTCACCTATCCCGCTTCAC"..., 76}], 2) = 8262
writev(4, [{"\n@C3A7DACXX140502:3:1209:20544:1"..., 8186}, {"GATCCTCGTCAGTCCTGAAGGAGTGTCAGCTT"..., 76}], 2) = 8262
writev(3, [{"\n+\nBA@CDEEEDEFEDBBDCDBDBCDCB@DDB"..., 8148}, {"??>ABEEECADDBBABBDCEBDCDCBECDBC@"..., 76}], 2) = 8224
writev(4, [{"\n+\n>>;ABCD@BEDFCDCDECCECCE?DADCE"..., 8148}, {">>;ABABBDDECEDECECCCECBBECCDDDFD"..., 76}], 2) = 8224
writev(3, [{"\n@C3A7DACXX140502:3:1209:20618:6"..., 8184}, {"TTGGAAGGCCAGGTCCAGTAACCGGCCCCATT"..., 76}], 2) = 8260
writev(4, [{"\n@C3A7DACXX140502:3:1209:20618:6"..., 8184}, {"ATTAGTAATTTCAGTGCCTCCTCCATCTTTAG"..., 76}], 2) = 8260
writev(3, [{"\n+\n?@>CCDFEEDDDCBDBDEBBCDB@CDBBB"..., 8148}, {"B@<DDDDFCEDEBBDDBDBDC@EBBECDDCEC"..., 76}], 2) = 8224
writev(4, [{"\n+\n>=;?C@?CBCCEDEAEDCDDBDDBDCDEB"..., 8148}, {">><A@BED@DDBDECBCBECCECDBDCDBEED"..., 76}], 2) = 8224
writev(3, [{"\n@C3A7DACXX140502:3:1209:20684:3"..., 8180}, {"ACCCAAATGAGATCTGTGTGCCAATGTCAGTG"..., 76}], 2) = 8256
writev(4, [{"\n@C3A7DACXX140502:3:1209:20684:3"..., 8180}, {"TCATCTGTGAACTCCACCAAGTTTTGTGCCTC"..., 76}], 2) = 8256

这是否意味着它正在写入缓冲区而不是刷新文件?

1 个答案:

答案 0 :(得分:1)

IO调优和性能改进既困难又耗时 - 您必须弄清楚应用程序的IO模式,并将代码和硬件与之匹配。甚至可能调整您的文件系统,甚至可能首先根据您的IO要求选择文件系统。它有点像阻抗匹配电气元件以获得最佳性能 - 从应用程序代码到磁盘磁头的所有方式本身都很重要,当您想要在设计极限下驱动系统时。

由于C ++ IO层之类的软件抽象,您无法在设计极限下驱动系统同时忽略设计......

  1. 对应用程序进行概要分析,以确定IO性能是否是瓶颈。如果它没有在IO上出现瓶颈,那么改进IO在很大程度上不会对应用程序性能有所帮助。

  2. strace下运行该应用程序,看看幕后发生了什么。应用程序是否正在进行大量seek()/lseek()系统调用?那些使C ++运行时库完成的缓冲无效,并且需要改进的IO方法。

  3. 如果您确实发现您的应用程序需要提高其IO性能,则可能需要在不使用C ++ IO例程的情况下重做IO - 它们并不快。请参见此处:std::fstream buffering vs manual buffering (why 10x gain with manual buffering)?

  4. 如果你只是在没有搜索的情况下阅读/编写大流,并且在数据从缓存中刷新之前没有重新读取数据,那么内核页面缓存只会减慢你的速度下。使用较低级别的基于C的IO例程,使用页面对齐的内存来读取/写入数据,并在打开时使用O_DIRECT标志来执行直接IO并绕过内核页面缓存。