我有一个Parallel.For和一个常规for循环做一些简单的算术,只是为了对Parallel.For
进行基准测试我的结论是,我的i5笔记本处理器上的常规速度更快。
这是我的代码
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int Iterations = int.MaxValue / 1000;
DateTime StartTime = DateTime.MinValue;
DateTime EndTime = DateTime.MinValue;
StartTime = DateTime.Now;
Parallel.For(0, Iterations, i =>
{
OperationDoWork(i);
});
EndTime = DateTime.Now;
Console.WriteLine(EndTime.Subtract(StartTime).ToString());
StartTime = DateTime.Now;
for (int i = 0; i < Iterations; i++)
{
OperationDoWork(i);
}
EndTime = DateTime.Now;
Console.WriteLine(EndTime.Subtract(StartTime).ToString());
StartTime = DateTime.Now;
Parallel.For(0, Iterations, i =>
{
OperationDoWork(i);
});
EndTime = DateTime.Now;
Console.WriteLine(EndTime.Subtract(StartTime).ToString());
StartTime = DateTime.Now;
for (int i = 0; i < Iterations; i++)
{
OperationDoWork(i);
}
EndTime = DateTime.Now;
Console.WriteLine(EndTime.Subtract(StartTime).ToString());
}
private static void OperationDoWork(int i)
{
int a = 0;
a += i;
i = a;
a *= 2;
a = a * a;
a = i;
}
}
}
这些是我的结果。重复哪个不会有太大变化:
00:00:03.9062234
00:00:01.7971028
00:00:03.2231844
00:00:01.7781017
那么为什么要使用Parallel.For?
答案 0 :(得分:9)
并行处理具有组织开销。从拥有100个任务和10个人的角度来考虑它。让10个人为你工作并不容易,只是组织谁除了实际做 100个任务之外还花费了多少时间。
因此,如果您想要并行执行某些操作,请确保组织并行度的工作量与实际工作负载相比是如此之小这样做是有意义的。
答案 1 :(得分:7)
在第一次深入研究多线程时,最常见的错误之一是多线程是Free Lunch的信念。
事实上,将您的操作分成多个较小的操作,然后可以并行运行,这将需要一些额外的时间。如果严重同步,您的任务可能会花费更多时间,等待其他任务释放锁定。
结果;并行化不值得花时间/麻烦,当每个任务都要做很少的工作时,就像OperationDoWork
一样。
考虑尝试一下:
private static void OperationDoWork(int i)
{
double a = 101.1D * i;
for (int k = 0; k < 100; k++)
a = Math.Pow(a, a);
}
根据我的基准测试,for
平均为5.7秒,而Parallel.For
在我的Core2Duo CPU上需要3.05秒(加速== ~1.87)。
在我的Quadcore i7上,for
的平均值为5.1秒,Parallel.For
的平均值为1.38秒(加速= = ~3.7)。
此修改后的代码可以很好地扩展到可用的物理内核数量。 Q.E.D.