sherrylso

C++博客 首页 新随笔 联系 聚合 管理
  18 Posts :: 0 Stories :: 124 Comments :: 0 Trackbacks

一、异步IO
        对于应用程序而言,有两种类型的IO调用:即同步IO与异步IO。其本质的区别是:同步IO会block当前的调用线程,而异步IO则允许发起IO请求的调用线程继续执行,等到IO请求被处理后,会通知调用线程。在windows平台上,应用程序可以调用CreateFile API, 并通过设置FILE_FLAG_OVERLAPPED标志来决定是否发起异步IO请求。
        对于异步的IO请求,其最大的好处是:慢速的IO请求相对于应用程序而言是异步执行,这样可以极大提高应用程序的处理吞吐量。发起IO请求的应用程序需要关心的是IO执行完成的结果,而不必忙等IO请求执行的过程。
       事实上,无论对于同步IO,还是异步IO,当IO请求发送到device driver后,device driver的执行总是异步的,当它接到IO请求之后,总会马上返回给IO System。而IO System是否立即返回给调用线程,则取决于FILE_FLAG_OVERLAPPED标志的设置,如下图:


二、异步IO的同步问题。
        我们使用异步IO,是为了提高应用程序的处理吞吐量。但是,当异步IO不再异步时(无论你是否设置FILE_FLAG_OVERLAPPED标志),应用程序的性能会受到极大的影响。根据Microsoft Knowledge Base 156932, 在下列几种情况下,异步IO会失去它的异步性,而表现出同步的性质:
1)如果文件使用了NTFS compression压缩,则system driver不会异步地存取这样的文件。
2)扩展文件长度的IO操作不会是异步操作。
3)Cache机制。如果IO操作使用了file system cache,则这样的IO操作会被当成同步IO,而非异步IO。
即使你使用了FILE_FLAG_OVERLAPPED标志。在这种情况下,
a.如果需要读取的数据已经在Cache里,那么I/O drivers会认为这样的IO请求可以被立即处理,其结果是ReadFile 或者WriteFile调用返回TRUE,表示是:同步处理完成。
b.如果需要读取的数据不在Cache里,windows NT的file system是使用page-faulting机制来实现cache管理,而page-faulting总是被同步处理, Windows NT没有提供异步的page-faulting机制。的确, file system driver使用了线程池来缓解这一问题,但是,当应用程序发起的IO请求足够多时,线程池还是不能应付的。
        在我们开发基于异步IO应用程序时,应该避免上述问题的出现,因为它们会使程序的性能大打折扣。
那么,对于Cache,我们如何避免呢?答案是:请使用FILE_FLAG_NO_BUFFERING标志。这个标志会使异步IO真实地异步执行。
三、性能的测试数据(仅供参考)。
      我在我的机器上,简单地对使用FILE_FLAG_NO_BUFFERING标志的异步IO,与不使用FILE_FLAG_NO_BUFFERING标志的异步IO进行了对比。
操作:顺序读取1G的文件。
x轴表示:每次读取的字节数(单位:K/每次)
Y轴表示:读取完成所需要的时间。(单位:millisecond)
注意:每次测试读取的内容总数是相等的(1000M)。
例如:如果每次读取128k,则需要读取8000次(128k*8000 = 1000M)。
如果每次读取256k,则需要读取4000次(256k*4000 = 1000M)。
粉红色的线没有使用FILE_FLAG_NO_BUFFERING标志,而黄色的线使用了FILE_FLAG_NO_BUFFERING标志。

从以上的数据,我们可以得出以下结论:
1) 当使用FILE_FLAG_NO_BUFFERING标志,应用程序的性能会极大提高,大概有50%的提高。
2)在使用异步IO的时候,还有一个注意的问题是:当你每次读取的字节数增大的时候,性能也会提高。尤其在小于1024k时,当增大次读取的字节数,性能都有明显的提高。在混合了网络传输等复杂因素的应用程序开发过程中,建议将该值设置为可配置的参数,通过调整该参数,使你的应用达到最好的性能。

参考资料:

1) Microsoft Knowledge Base 156932

2)  Microsoft Windows Internals, Fourth Edition. 

posted on 2007-07-01 18:45 爱上龙卷风 阅读(9005) 评论(6)  编辑 收藏 引用

Feedback

# re: 异步IO性能探究 2007-09-12 01:51 ^Shhh^
你有没有试过这样和做filemapping的效率比较?  回复  更多评论
  

# re: 异步IO性能探究 2008-01-11 22:11 爱上龙卷风
@^Shhh^
没有。
好像没什么可比性吧。两个的应用场合不尽相同。
  回复  更多评论
  

# re: 异步IO性能探究 2008-04-28 15:59 拖鞋
能把测试代码给出来么?或者发给我也行
我进行了测试,结果使用FILE_FLAG_NO_BUFFERING的效率更低下……
  回复  更多评论
  

# re: 异步IO性能探究 2008-04-28 16:00 拖鞋
哦,我的邮件是:jwpfish@gmail.com  回复  更多评论
  

# re: 异步IO性能探究 2008-05-29 17:04 爱上龙卷风
@拖鞋
不好意思,我当时的代码找不到了,不过我可以给你一个参考资料:
http://support.microsoft.com/kb/156932
看能不能帮到你。
  回复  更多评论
  

# re: 异步IO性能探究 2014-10-18 10:42 LZG
你好,
在下列几种情况下,异步IO会失去它的异步性
这个结论是怎么得出的,有文章可以看看吗,我想知道这几种情况为什么不支持异步。

希望可以交流一下,我的邮箱 582959666@qq.com
  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理