我有以下程序(我从 http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx 获得)使用 Parallel.For 循环拆分任务
class Program
{
static void Main(string[] args)
{
var watch = Stopwatch.StartNew();
Parallel.For(2, 20, (i) =>
{
var result = SumRootN(i);
Console.WriteLine("root {0} : {1} ", i, result);
});
Console.WriteLine(watch.ElapsedMilliseconds);
Console.ReadLine();
}
public static double SumRootN(int root)
{
double result = 0;
for (int i = 1; i < 10000000; i++)
{
result += Math.Exp(Math.Log(i) / root);
}
return result;
}
}
当我多次运行此测试时,我得到以下时间:
1992、2140、1783、1863 毫秒等
我的第一个问题是,为什么时间总是不同?我每次都在做完全相同的计算,但每次的时间都不同。
现在,当我添加以下代码以使用我的 CPU 上所有可用的处理器时:
var parallelOptions = new ParallelOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount (On my CPU this is 8)
};
Parallel.For(2, 20, parallelOptions, (i) =>
{
var result = SumRootN(i);
Console.WriteLine("root {0} : {1} ", i, result);
});
我注意到执行时间实际上增加了!!现在是时候了:
2192、3192、2603、2245 毫秒等
为什么这会导致时间增加?我用错了吗?
最佳答案
By default,
For
andForEach
will utilize however many threads the underlying scheduler provides. Changing MaxDegreeOfParallelism from the default only limits how many concurrent tasks will be used.
这意味着将 MaxDegreeOfParallelism
设置为处理器数量实际上会限制 Parallel.For
循环的容量,以便为工作负载使用最佳线程数.例如,我有一个迁移作业在大约 600 次长时间运行的代码迭代中使用近 60 个线程,远远超过您尝试设置的每个处理器 1 个线程限制。
MaxDegreeOfParallelism
或 ThreadPool.SetMaxThreads
仅应在您明确需要阻止超过给定数量的线程执行时使用。例如,如果使用 Access 数据库,我会将其设置为 64,因为这是 Access 可以为单个进程处理的最大并发连接数。
关于c# - MaxDegreeOfParallelism = Environment.ProcessorCount 减慢了我 CPU 的执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20806238/