我正在编写一个使用第三方库执行大量计算的应用程序。
该库在内部实现并行性并产生给定数量的线程。我想运行这个库的几个(动态计数)实例,因此最终会过度订阅cpu。
有什么方法可以增加流程中所有线程的“时间量”,以便例如具有正常优先级的所有线程很少上下文切换(yield),除非它们通过例如明确地产生。信号灯?
这样我就可以避免过度订阅cpu的大部分性能开销。请注意,在这种情况下,我不关心一个线程是否缺乏几秒钟。
编辑:
这样做的一个复杂方法是手动执行线程调度。
这种方法有什么主要缺点吗?不确定恢复/暂停线程的开销是多少?
答案 0 :(得分:4)
您无需做任何特别的事情。任何体面的调度程序都不允许非强制上下文切换消耗大量的CPU资源。不应使用任何没有合适调度程序的操作系统。
超额订购CPU的性能开销不非强制上下文切换的成本。为什么?因为调度程序可以简单地避免这些。调度程序仅在有益处时才执行非强制上下文切换。绩效成本如下:
完成工作可能需要更长时间,因为在工作开始和工作完成之间,其他工作会完成更多工作。
其他线程会为其堆栈和相关的其他跟踪信息消耗内存。
更多线程通常意味着更多争用(例如,当分配内存时),这可能意味着更多强制上下文切换,其中线程必须被切换,因为它无法前进。
< / LI> 醇>当您知道调度程序不知道的重要事项时,您只想尝试更改调度程序的行为。没有什么比这更好的了。所以默认行为就是你想要的。
答案 1 :(得分:2)
这种方法有什么主要缺点吗?不知道是什么开销 恢复/暂停线程是?
是,恢复/暂停线程是非常非常危险的活动,在程序的用户模式中完成。所以不应该使用它(几乎从不)。此外,我们不应该使用这些概念来实现任何现代调度程序为我们所做的事情。这也是在这个问题的其他帖子中提到的。
以上内容适用于任何操作系统,但从SO post标签来看,我认为已经要求基于 Microsoft Windows 的系统。现在,如果我们从MSDN中了解SuspendThread(),我们会得到以下结果:
&#34;此功能主要供调试器使用。 无意用于线程同步。在拥有同步对象(如互斥锁或临界区)的线程上调用SuspendThread,如果调用线程尝试获取挂起线程所拥有的同步对象,则会导致死锁。
因此,请考虑线程已获取某些资源的情况(隐式地。不是代码的一部分...来自库或内核模式),如果我们暂停该线程,这将导致神秘的死锁情况,因为该进程的其他线程会等待那个特定的资源。事实是我们在程序中不确定(在任何时候)任何正在运行的线程获取什么样的资源,暂停/恢复线程不是一个好主意。