【发布时间】:2014-01-15 08:57:02
【问题描述】:
我有以下程序(我从 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 毫秒等
为什么会导致次数增加?我用错了吗?
【问题讨论】:
-
当您运行测试时,您的系统上还运行着什么?你是在 Release 模式下编译吗?是否附加了调试器?是否附加了探查器?
-
要获得真正可比较的结果,请避免从这些线程输出到控制台。
-
我打开了 Outlook、EverNote 和 Chrome 网络浏览器。
-
它处于发布模式,没有附加任何调试器或任何东西。
-
我认为这就是鸽子洞原理。您要求 8 个线程执行 18 个作业,最后 2 个作业花费的时间与 8 个作业一样多。当您取消限制时,TP 调度程序允许启动超过 个线程,因为它们需要太多时间。这会减慢每个工作,但可以摆脱最后两个。
标签: c# task-parallel-library parallel.foreach