这段代码来自微软的文章http://msdn.microsoft.com/en-us/library/dd460703.aspx,有一些小改动:
const int size = 10000000;
int[] nums = new int[size];
Parallel.For(0, size, i => {nums[i] = 1;});
long total = 0;
Parallel.For<long>(
0, size, () => 0,
(j, loop, subtotal) =>
{
return subtotal + nums[j];
},
(x) => Interlocked.Add(ref total, x)
);
if (total != size)
{
Console.WriteLine("Error");
}非并行循环版本是:
for (int i = 0; i < size; ++i)
{
total += nums[i];
}当我使用StopWatch类测量循环执行时间时,我看到并行版本比以前慢了10-20%。测试是在Windows 7 64位,Intel i5-2400 CPU,4核,4 GB RAM上进行的.当然,在发布配置中。
在我的实际程序中,我试图计算一个图像直方图,并行版本运行速度要慢10倍。当每次循环调用都非常快时,这样的计算任务能否成功地与TPL并行?
编辑
最后,当我将整个图像分割成一定数量的块时,我成功地用Parallel.For减少了50%的直方图计算执行时间。现在,每个循环体调用都处理整个块,而不是一个像素。
发布于 2013-08-13 07:56:46
因为Parallel.For应该被用来处理一些杂乱无章的事情,而不是简单的数字之和!仅仅使用委托(j, loop, subtotal) =>可能就足以给出10%-20%的时间。我们甚至都没说到线程的开销。在for循环中看到一些针对委托夏季的基准,不仅看到“真实世界”时间,而且看到CPU时间,这将是很有趣的。
我甚至添加了一个与Parallel.For<>委托相同的“简单”委托的比较。
嗯..。现在我有一些32位的数字,在我的个人电脑上(一个AMD六核)
32 bits
Parallel: Ticks: 74581, Total ProcessTime: 2496016
Base : Ticks: 90395, Total ProcessTime: 312002
Func : Ticks: 147037, Total ProcessTime: 468003并行在墙时间稍微快一点,但在处理器时慢8倍:)
但在64比特:
64 bits
Parallel: Ticks: 104326, Total ProcessTime: 2652017
Base : Ticks: 51664, Total ProcessTime: 156001
Func : Ticks: 77861, Total ProcessTime: 312002修改后的代码:
Console.WriteLine("{0} bits", IntPtr.Size == 4 ? 32 : 64);
var cp = Process.GetCurrentProcess();
cp.PriorityClass = ProcessPriorityClass.High;
const int size = 10000000;
int[] nums = new int[size];
Parallel.For(0, size, i => { nums[i] = 1; });
GC.Collect();
GC.WaitForPendingFinalizers();
long total = 0;
{
TimeSpan start = cp.TotalProcessorTime;
Stopwatch sw = Stopwatch.StartNew();
Parallel.For<long>(
0, size, () => 0,
(j, loop, subtotal) =>
{
return subtotal + nums[j];
},
(x) => Interlocked.Add(ref total, x)
);
sw.Stop();
TimeSpan end = cp.TotalProcessorTime;
Console.WriteLine("Parallel: Ticks: {0,10}, Total ProcessTime: {1,10}", sw.ElapsedTicks, (end - start).Ticks);
}
if (total != size)
{
Console.WriteLine("Error");
}
GC.Collect();
GC.WaitForPendingFinalizers();
total = 0;
{
TimeSpan start = cp.TotalProcessorTime;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < size; ++i)
{
total += nums[i];
}
sw.Stop();
TimeSpan end = cp.TotalProcessorTime;
Console.WriteLine("Base : Ticks: {0,10}, Total ProcessTime: {1,10}", sw.ElapsedTicks, (end - start).Ticks);
}
if (total != size)
{
Console.WriteLine("Error");
}
GC.Collect();
GC.WaitForPendingFinalizers();
total = 0;
Func<int, int, long, long> adder = (j, loop, subtotal) =>
{
return subtotal + nums[j];
};
{
TimeSpan start = cp.TotalProcessorTime;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < size; ++i)
{
total = adder(i, 0, total);
}
sw.Stop();
TimeSpan end = cp.TotalProcessorTime;
Console.WriteLine("Func : Ticks: {0,10}, Total ProcessTime: {1,10}", sw.ElapsedTicks, (end - start).Ticks);
}
if (total != size)
{
Console.WriteLine("Error");
}https://stackoverflow.com/questions/18203388
复制相似问题