C# 如何最大限度地提高特定代码段没有上下文切换的机会?
我的应用程序中有一段对时间要求严格的代码。我将运行它的线程设置为最高优先级 - 这是我能做的最多的事情。
是否有关于如何使该线程中运行的部分代码被中断尽可能少的次数(更少发生上下文切换)的建议?
代码并不复杂。我用内联代码替换了所有方法调用,并且不使用任何高级内容(例如不使用 LINQ)。大多数运算都是算术运算。只有一次字符串比较(我正在考虑如何消除它)。一半数学涉及整数,一半涉及双精度数。
代码是 x86 .NET 4 C#。在单个 Xenon X3450 W2008R2 上运行。单一应用程序服务器。
(不幸的是,数据来自 3d party API,它不支持 x64(讨厌它!))
我很乐意与经验丰富的开发人员进行成熟的讨论。
PS 服务器没有分页文件,因此也不会发生硬页面错误(没有不需要的 IO 操作)。
I have time-critical piece of code in my app. I made the thread which runs it Highest priority - that's the most I could do.
Is there any suggestions on how to make part of the code run in this thread to be interrupted as few times as possible (less context switch occurred) ?
The code is not complicated. I replaced all the method calls with inlined code and I don't use anything of high level (like no LINQ). The most of operations are arithmetic. There is only one comparison of strings (I am thinking of ways how to rid of it). Half of maths are with ints and half with doubles.
The code is x86 .NET 4 C#. Runs on single Xenon X3450 W2008R2. Single app server.
(Unfortunately data is coming from 3d party API which doesn't support x64 (hate it!))
I'd appreciate grown-up discussion with experienced developers.
P.S. The server has no paging file so hard page faults wont happen either (no unwanted IO operations).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在上下文切换方面,您唯一需要担心的是阻塞您的线程。因此,使用 LINQ(即 LINQ-to-objects,显然是 LINQ-to-SQL 或任何涉及阻塞的内容!)应该没有问题。任何类型的算术或调用方法等也不会阻塞线程,因此对上下文切换没有影响。
正如您所指出的,影响上下文切换的另一件事是优先级。但不仅仅是线程优先级,还有进程的优先级。您可以使用 SetPriorityClass 来增加您的进程的优先级为
ABOVE_NORMAL_PRIORITY_CLASS
(我不会费心将其设置得更高),然后将线程的优先级也设置为高于正常。然而,一般来说,优先级实际上仅在涉及时间时才有用(即确保您的进程尽可能快地响应外部输入(网络、用户输入、磁盘 I/O)) )。它实际上对线程的实际吞吐量影响很小,除非您同时运行其他同样受 CPU 限制的进程。但如果是这样的话,那么摆弄优先级无论如何都不会是一个可行的长期解决方案。这是因为您会发现,通过将其中一个进程设置为更高的优先级,它将完全使其他进程处于饥饿状态,并且它们将永远不会运行。
所以无论如何,在调整线程和进程优先级之前我会仔细考虑。并且,一如既往,测试,测试,测试!
The only thing you need to worry about in terms of context switches, is blocking your thread. So there should be no problem with using LINQ (that is, LINQ-to-objects, obviously LINQ-to-SQL or whatever would involve blocking!). Any sort of arithmetic or calling methods and so on will also not block the thread and so have no impact on context switches.
The other thing that affects context switching is, as you noted, priority. But not just thread priority, also your process's priority. You can use SetPriorityClass to increase your process's priority to
ABOVE_NORMAL_PRIORITY_CLASS
(I wouldn't bother putting it higher than that) and then set your thread's priority to Above Normal as well.However, in general, priorities are really only useful when it's a matter of timing (that is, making sure your process responds to external input (network, user input, disk I/O) as fast as possible). It will actually have very little impact on your thread's actual throughput, unless you have other processes that are also CPU-bound running at the same time. But if that's the case, then fiddling with priorities is not going to be a viable long-term solution anyway. This is because you'll find that by setting one of the processes to a higher priority, it'll completely starve the other processes and they'll never run.
So anyway, I would carefully consider things before adjusting thread and process priorities. And, as always, test, test, test!
如果您改为使用非托管 WINAPI 代码,则 SetThreadPriority 函数还支持 THREAD_PRIORITY_TIME_CRITICAL(高于 THREAD_PRIORITY_HIGHEST)。
还值得提高线程运行所在进程的优先级(实际优先级取决于线程和进程优先级的组合)。
您还应该避免在线程上进行 I/O 调用(这可能会阻塞)。走向一个也许可笑的极端,您还可以避免在其他线程上进行 I/O 调用(这可以暂时提高这些线程的优先级)。
If you make that unmanaged WINAPI code instead, the SetThreadPriority function also supports a THREAD_PRIORITY_TIME_CRITICAL (higher than THREAD_PRIORITY_HIGHEST).
It's also worth boosting the priority of the process in which the thread is running (actual priority depends on a combination of thread and process priority).
You should also avoid making I/O calls on the thread (which could block). Taking it to a perhaps-ridiculous extreme you could also avoid making I/O calls on other threads (which could temporarily boost the priority of those threads).