2013-01-19 49 views
4

我是Grand Central Dispatch的忠实粉丝,我最近一直在寻找dispatch_io_*调用系列。很容易看到这个API对于网络I/O(慢速,高延迟)有用。也就是说,dispatch_io_create_with_path的存在意味着在本地文件系统上使用。 (是的,我知道路径也可能指向远程网络文件系统上的资源,但无论如何...)在使用它时,我发现使用dispatch_io_*似乎带来相当大的开销,与使用简单阻止I/O调用(read,write等)。这种减速似乎主要来自内核同步原语,因为块在队列之间来回编组。在我一直在玩的示例工作负载(非常多的I/O限制)下,速度可能会下降10倍。首先,它看起来像dispatch_io永远不会是一个赢得健谈(小颗粒)I/O。dispatch_io很好地解决了哪些本地存储I/O模式?

我认为,在具有单一本地物理存储卷的单机的常见情况下,I/O请求将在设备级别被有效串行化。从那里,我发现自己有了这两个想法:

  • 如果您的工作负载是CPU限制的,那么根据定义,您可以比读取/写入数据更快。
  • 如果使用dispatch_io,您的工作负载是I/O限制(在这种情况下 - 一个本地物理卷),则无法使您的磁盘以更快的速度为您提供数据。

从那里,我想也许这个API的甜蜜点可能在中间 - 一个工作负载之间的CPU和I/O绑定,但在这一点上我有点儿认为自己到了一个角落,所以我想我会问StackOverflow。

我会接受描述具有这些先决条件(即单机,单本地物理磁盘)的“真实世界”工作流程的第一个答案,其中使用dispatch_io会显着提高性能。

回答

7

从本地文件系统分派I/O的主要用例是较大文件的异步IO,或同时读/写多个文件的异步IO(尤其是如果可以逐步处理文件的内容)。

本地文件系统的调度I/O针对吞吐量超过延迟进行了优化(例如,它在实际IO系统调用之前执行分块和建议读取以优化通过内核和驱动程序在IO路径上的流水线吞吐量)。

鉴于IO系统调用在后台线程上的异步执行,调度IO将永远不会超出使用阻塞系统调用执行的小文件IO的延迟,特别是在没有其他IO活动正在进行时。

来自WWDC11的GCD会话详细介绍了调度I/O,并对直读()系统调用实现的吞吐量改进进行了比较,以读取各种大小的许多文件。