3

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

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

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

4

2 回答 2

3

实际上,跨核上下文切换对应用程序性能有害的可能性很小。

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

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

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

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

作为旁注,与 LBushkin 的建议相反,它BeginThreadAffinity不会帮助您提高处理器亲和力:它只会将 .NET 线程固定到特定的操作系统线程,而不是特定的核心。

有用的链接:

[1]使用并发实现可扩展性
[2]量化上下文切换的成本
[3]进行上下文切换需要多长时间?

于 2013-06-25T20:55:41.703 回答
1

您可以将其中一些线程关联到单个内核。但是这样做时您必须非常小心——因为它实际上可能会通过阻止 CLR/OS 将线程调度到可用内核来降低性能。

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

于 2010-07-28T15:40:00.223 回答