【问题标题】:Minimize the number of cross-core context switches最小化跨核上下文切换的次数
【发布时间】:2010-07-28 15:30:41
【问题描述】:

我最近在应用程序分析方面做了很多试验(使用 Visual Studio 性能向导)。在使用并发指标时,我注意到当应用程序使用多个线程(后台和前台)运行时,跨核上下文切换率非常高。

知道通常大量的跨核上下文切换可能会损害应用程序性能,因此我想将其减少到最低限度。

除了最小化同时运行的线程数量之外,在 .NET 应用程序中执行此操作的可能方法是什么?

【问题讨论】:

    标签: .net performance profiling cpu-usage cpu-speed


    【解决方案1】:

    跨核心上下文切换实际上极不可能损害应用程序性能。

    任何上下文切换都会产生约 1-4 微秒的直接成本来保存/恢复线程状态,加上缓存预热的间接成本。间接成本取决于许多因素,例如数据位置和访问模式,并且变化很大:从数百纳秒(几乎不增加总上下文切换成本)到数百微秒,将总成本增加两个数量级。

    虽然可以合理地预期缓存预热将需要更长的时间来进行跨核心上下文切换(如果新核心不与旧核心共享缓存),但仍需要将线程调度到同一个核心缓存预热,因为部分或全部线程的数据将被中间内核上执行的其他线程从缓存中逐出。

    在任何情况下,与约 30-120 毫秒的线程执行量(上下文切换之间的时间)相比,上下文切换的总成本仍然不明显。

    只有在病态的情况下,即当线程长时间使用完全适合非共享缓存的相同数据集时,跨核上下文切换可能会对性能产生明显影响。大多数时候他们不会成为瓶颈。

    附带说明,与 LBushkin 的建议相反,BeginThreadAffinity 不会帮助您提高处理器亲和力:它只会将 .NET 线程固定到特定的操作系统线程,不会固定到特定的内核。

    有用的链接:

    [1]Using Concurrency for Scalability
    [2]Quantifying The Cost of Context Switch
    [3]How long does it take to make a context switch?

    【讨论】:

      【解决方案2】:

      您可以将其中一些线程关联到单个内核。但是你必须be extremely careful when doing so - 因为它实际上可能会通过阻止 CLR/OS 将线程调度到可用内核来降低性能。

      为此,您可以使用BeginThreadAffinity 方法强制线程保持固定到特定处理器或内核的标识。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-10
        • 1970-01-01
        • 2017-09-16
        • 1970-01-01
        • 1970-01-01
        • 2019-03-17
        • 1970-01-01
        相关资源
        最近更新 更多