我知道设置线程优先级是堆栈溢出时的一个禁忌主题,但我确信我的应用程序是提高优先级的一个很好的候选者。为了证明这一点,我已经解释了下面的背景。现在的问题是如何有效地做到这一点?
该应用程序是.NET 4(C#)控制台应用程序,它执行复杂的算法,执行时间约为5小时。该算法根本不是内存密集型的,只是处理器密集型。它执行数字运算并且不执行任何磁盘I / O,数据库连接,网络连接等。应用程序的输出只是一个数字,它最后写入控制台。换句话说,该算法完全是自包含的,没有依赖性。
该应用程序在运行Windows Server的专用16核64位计算机上运行,其可用RAM远远超过其要求(8GB)。通过专用,我的意思是服务器已被采购以独家运行此应用程序。
我已经通过广泛的分析,花哨的数学快捷方式和尖锐的黑客攻击来尽可能地优化代码。
以下是伪代码的整体结构:
public static void Main ()
{
Process.GetCurrentProcess().PriorityBoostEnabled = true;
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
// Of course this only affects the main thread rather than child threads.
Thread.CurrentThread.Priority = ThreadPriority.Highest;
BigInteger seed = SomeExtremelyLargeNumber; // Millions of digits.
// The following loop takes [seed] and processes some numbers.
result1 = Parallel.For(/* With thread-static variables. */);
while (true) // Main loop that cannot be parallelized.
{
// Processes result1.
result2 = Parallel.For(/* With thread-static variables. */);
// Processes result2.
result1 = Parallel.For(/* With thread-static variables. */);
if (result1 == criteria)
break;
// Note: This loop does not need to sleep or care about system responsiveness.
}
}
现在基于SO上的线程优先级相关问题,我认为使用ThreadPool的任何东西都不应该在优先级方面被搞乱。所以如果我需要切换到手动线程,那就这样吧。
问题:
答案 0 :(得分:2)
使用这样的应用程序,我希望更改优先级,使整个运行时间有0%的差异。如果您已经完全消耗了CPU使用率,并且所有16个内核都在100%做真正的工作,那么您可以做的就更多了。
答案 1 :(得分:1)
您不需要为单个线程设置优先级,只需为整个过程执行此操作,因为它的大多数线程显然都在做重要的工作。
然而,我不认为它会对像您这样的CPU密集型应用产生任何影响。可强制抢占自己进程的唯一进程是传统上受大多数操作系统青睐的I / O密集型应用程序,但由于您拥有专用计算机,因此不会出现问题(同样,Windows Server在我的体验中非常轻量级) ,如果您的应用程序是唯一正在运行的应用程序,它将不会干扰。
作为旁注:
该算法根本不是内存密集型的,只是处理器 密集。它执行数字运算并且不执行任何磁盘I / O, 数据库连接,网络连接等
它不执行“明显的”I / O操作这一事实并不意味着它不会占用大量内存。如果您正在处理大型数组或其他数据结构,CPU将不断地向主存储器发出读/写操作,并且正在进行大量工作以在各种存储器级别之间移动数据。如果处理不当,即使只处理数字也会对程序的性能产生负面影响。
答案 2 :(得分:1)
我的代码可以更改进程和线程的优先级。
public void SetPriorityProcessAndTheards(string nameProcess,ProcessPriorityClass processPriority, ThreadPriorityLevel threadPriorityLevel)
{
foreach(Process a in Process.GetProcessesByName(nameProcess))
{
a.PriorityBoostEnabled = true;
a.PriorityClass = processPriority;
foreach(ProcessThread processThread in a.Threads)
{
processThread.PriorityLevel = threadPriorityLevel;
processThread.PriorityBoostEnabled = true;
}
}
}
答案 3 :(得分:0)
我希望您将线程数限制为核心/线程数。有时并行任务库使用太多线程。对于你的cpumaxed进程,corecount或threadcount(添加超线程假冒伪造)最好,所以提供并修复threadcount;
// Create a ParallelOptions object and supply this to the Parallel.For()
var po = new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount}
Parallel.For(,,po,);
// Environment.ProcessorCount gives number of Cores (NOT processors)
// Never found out how to detect fake cores or hyperthreads, check Task Monitor ;-)
您可以为所有parallel.For()语句重用po对象。即使在CPU绑定的线程应用程序上,我也从未真正受益于优先级摆弄。