C#如何最大限度地利用该代码的特定部分没有上下文切换的机会?
-
28-09-2019 - |
题
我的应用程序中有时间关键的代码。我制作了将其运行最高优先级的线程 - 这是我能做的最大的。
对如何使该线程中的一部分运行以尽可能少的次(发生上下文开关)中断有任何建议吗?
代码并不复杂。我用内线代码替换了所有方法调用,但我不使用任何高级别(例如没有LINQ)。大部分操作都是算术的。琴弦只有一个比较(我正在考虑如何摆脱它)。一半的数学是ints,一半是双打。
代码为x86 .NET 4 C#。在单氙X3450 W2008R2上运行。单个应用程序服务器。
(不幸的是,数据来自3D Party API,不支持X64(讨厌它!))
我很高兴与经验丰富的开发人员讨论。
PS服务器没有分页文件,因此硬故障也不会发生(也没有不需要的IO操作)。
解决方案
在上下文开关方面,您唯一需要担心的是阻止线程。因此,使用LINQ应该没有问题(即Linq-Objects,显然是Linq-to-SQL或任何涉及阻止的东西!)。任何类型的算术或调用方法等等也不会阻止线程,因此对上下文开关没有影响。
正如您指出的那样,影响上下文切换的另一件事是优先。但不仅是主题优先级,还包括您的过程的优先级。您可以使用 SetPriorityClass 提高过程的优先事项 ABOVE_NORMAL_PRIORITY_CLASS
(我不会理会地将其提高),然后将您的线程的优先级设置为高于正常状态。
但是,总的来说,优先级才真正有用 定时 (也就是说,确保您的流程尽可能快地响应外部输入(网络,用户输入,磁盘I/O))。实际上,它对线程的实际吞吐量几乎没有影响,除非您还有其他同时运行CPU的过程。但是,如果是这样,那么无论如何,要摆弄优先级就不会成为可行的长期解决方案。这是因为您会发现,通过将其中一个流程设置为更高的优先级,它将完全饿死其他过程,而它们将永远不会运行。
因此,无论如何,在调整线程和过程优先级之前,我会仔细考虑事情。并且,一如既往,测试,测试,测试!
其他提示
如果您使该不受管理的Winapi代码代替,则SetThreadPriority函数还支持thread_priority_time_critical(高于thread_priority_highest)。
还值得提高线程正在运行的过程的优先级(实际优先级取决于线程和过程优先级的组合)。
您还应避免在线程上拨打I/O呼叫(可能会阻止)。将其带到一个可能是讽刺的极端情况下,您也可以避免在其他线程上拨打I/O呼叫(这可能会暂时提高这些线程的优先级)。