执行并行、循环作为低优先级CPU操作的最简单方法是什么



背景
从历史上看,我不必写太多与线程相关的代码。我熟悉这个过程,当需要时,我可以使用System.Threading来做我需要做的事情。然而,我的大部分经验都停留在.Net 2.0的世界里(啊!),在最新版本的.Net.中,我需要一些帮助来执行一个非常简单的任务

我需要写一个简单的并行作业,但我更希望它作为一个低优先级的任务执行,不会让我的电脑缓慢停止。

下面是一个简单的平行示例,演示了我试图完成的工作类型。在这个例子中,我取一个随机数,如果新值大于已经发现的最后一个最大的随机数,我就会存储它。

请理解,这个例子的目的是严格地表明我有一个计算,我希望重复执行、比较和存储。我理解变量锁定的必要性,也知道这段代码并不完美。然而,这是一个非常简单的例子,说明了我需要完成的事情的本质。如果你运行这个代码,你的CPU将陷入严重的停顿。

int i = 0;
ThreadSafeRNG r = new ThreadSafeRNG();
ParallelOptions.MaxDegreeOfParallelism = 4; //Assume I have 8 cores.
Parallel.For(0, Int32.MaxValue, (j, loopState) => 
{
    int k = r.Next();
    if (k > i) k = i;
}

我如何并行地完成这项工作,并将其作为低优先级CPU作业执行。与循环的标准相比,上述机制提供了巨大的性能改进。然而,代价是我不能使用我的电脑,即使设置了MaxDegreeOfParallelism选项。

我能做什么?

因为Parallel.For使用ThreadPool线程,所以不能将线程的优先级设置为低。但是,您可以更改整个应用程序的优先级

Process currentProcess = Process.GetCurrentProcess();
ProcessPriorityClass oldPriority = currentProcess.PriorityClass;
try
{
    currentProcess.PriorityClass = ProcessPriorityClass.BelowNormal;
    int i = 0;
    ThreadSafeRNG r = new ThreadSafeRNG();
    ParallelOptions.MaxDegreeOfParallelism = 4; //Assume I have 8 cores.
    Parallel.For(0, Int32.MaxValue, (j, loopState) => 
    {
        int k = r.Next();
        if (k > i) k = i;
    }
}
finally
{
    //Bring the priority back up to the original level.
    currentProcess.PriorityClass = oldPriority;
}

如果你真的不想降低整个应用程序的优先级,请将此技巧与某种形式的IPC(如WCF)结合起来,让你缓慢的长时间运行的操作在第二个进程中运行,然后根据需要启动并终止。

使用Parallel.For方法,无法设置线程优先级,因为它们是ThreadPool线程。

您最好的选择是将ParallelOptions.MaxDegreeOfParallelism设置为ProcessorCount - 1,这样您就有了一个自由的核心来做其他事情(例如处理GUI)。

相关内容

最新更新