【问题标题】:Asynchronous operations performance异步操作性能
【发布时间】:2009-02-22 22:34:45
【问题描述】:

.NET 中asynchronous programming 的功能之一是在长时间运行的操作执行期间节省线程。 FileStream 类可以设置为允许异步操作,允许运行(例如)复制操作,而实际上不使用任何线程。令我惊讶的是,我发现运行异步流复制不仅执行速度更慢,而且比等效的同步流复制使用更多的处理能力。

是否进行了任何基准测试来比较同步和异步操作执行(文件、网络等)?如果异步操作比同步操作慢几倍,那么执行异步操作而不是跨越单独的线程并在服务器环境中执行同步操作真的有意义吗?

【问题讨论】:

    标签: .net asynchronous filestream


    【解决方案1】:

    引用您在评论中包含的文章对@Alex 的回复。

    在 I/O 请求被 预计会占用大量 时间,例如刷新或备份 大数据库或慢 通信链路,异步 I/O 通常是一种优化的好方法 处理效率。然而,对于 相对快速的 I/O 操作, 处理内核 I/O 的开销 请求和内核信号可能会使 异步 I/O 不太有利, 特别是如果有很多快速 I/O 需要进行操作。在这个 在这种情况下,同步 I/O 会更好。 机制与实施 如何完成这些的详细信息 任务因类型而异 使用的设备句柄和 应用程序的特殊需求。 换句话说,通常有 解决问题的多种方法。

    FWIW,我认为@Alex 是正确的,有另一个线程在运行与您的 I/O 请求相关的内核代码。但是,该线程不由您的应用程序管理。运行内核代码的线程本身可能会阻塞设备 I/O 请求并等待实际硬件完成请求,然后再向您的用户模式线程发出信号,但它仍然存在。

    不应将使用异步线程视为提高任何特定请求速度的一种方法,而是一种通过允许您的应用程序在等待相对较慢的 I/O 的同时继续处理其他任务来提高整体效率的方法.

    【讨论】:

    • 异步 I/O 在 Windows NT 上不使用线程。存储驱动程序可能会选择使用内核工作线程,但这会非常低效,因为线程在内核模式下很昂贵。
    • 我认为这确实是语义问题。无论您是使用内核进程还是生成新的内核线程,仍有代码在内核模式下代表调用线程运行以执行 I/O 操作。您无法摆脱一些运行以服务 I/O 操作的内核代码。
    • 该操作不在单独的线程中运行。存储设备能够在无人值守的情况下执行 I/O,并在完成时发出信号中断。该中断的“清理工作”在现有线程之一中完成,而无需创建新线程。
    • 我没有说它创建了一个新线程。我说它在与用户线程不同的线程中运行。
    【解决方案2】:

    实际上,文件 i/o 实际上异步的条件是相当具体的,即使在本机 Win32 级别也是如此。详情请见this article

    【讨论】:

    • 澄清一下:那篇文章没有提到异步与同步 I/O 性能。所有关于提高异步性能的技巧也适用于同步性能。详情见我的回答。
    【解决方案3】:

    您确定您的复制操作基准测试正确吗?任何异步操作都只是创建新线程并在新线程中运行该操作,而让主线程去做其他事情。

    与自己创建线程相比,异步操作主要提供了一些简化(更少的代码行),但它们不应该比创建新线程更影响性能。

    【讨论】:

    • 纯异步操作在硬件上中继以调用回调,并且它们不跨越新线程
    • 什么是“纯异步操作”?你能提供一些链接吗?
    • 他的意思是对硬件的IO调用
    猜你喜欢
    • 2023-03-16
    • 2014-06-15
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2017-06-29
    • 2018-10-30
    • 1970-01-01
    相关资源
    最近更新 更多