【发布时间】:2015-03-13 20:26:11
【问题描述】:
最近我玩过并行循环。我从简单的任务开始,因为它正在填充一个巨大的数组。
但是,当代码不是并行时,创建时间是半秒,而当代码是并行时,创建时间是 6.03 秒(原文如此!)。
怎么会?
我认为没有比我做的更简单的任务来展示并行性的好处,即将大型任务划分为较小的任务。
谁能解释一下?
12GB RAM,i7 Extreme 980(6 核 + 6 虚拟)3.06G
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ParallelLoop
{
class Program
{
static void Main(string[] args)
{
int Min = 0;
int Max = 10;
int ArrSize = 150000000;
Stopwatch sw2 = new Stopwatch();
Stopwatch sw3 = new Stopwatch();
int[] test2 = new int[ArrSize];
int[] test3 = new int[ArrSize];
Random randNum = new Random();
sw2.Start();
for (int i = 0; i < test2.Length; i++)
{
test2[i] = i;
//test2[i] = randNum.Next(Min, Max);
}
sw2.Stop();
Console.ReadKey();
Console.WriteLine("Elapsed={0}", sw2.Elapsed);
sw3.Start();
Parallel.For(0, test3.Length, (j) =>
{
test3[j] = j;
//test3[j] = randNum.Next(Min, Max);
}
);
sw3.Stop();
Console.WriteLine("Elapsed={0}", sw3.Elapsed);
Console.ReadKey();
}
}
}
【问题讨论】:
-
这里只是猜测,但是将数组槽设置为整数是如此之快,以至于为此使用线程的成本可能不仅仅是在单个循环中设置所有槽。设置和切换线程非常非常昂贵,因此如果任务非常简单,则不值得将其拆分。如果单个任务很复杂并且您有许多相同的任务,那么使用线程的成本通常与任务成本相比相形见绌。
-
尝试更复杂的东西,可能是编译器正在使用仅在前者中检测到的重手优化。例如,将您的负载转换为可以更快的矢量化负载。
-
只有在实际工作时才应该使用并行。在这里,您的问题很简单,一个内核可以轻松地最大化您的内存带宽。在这种情况下,添加并行性只会减慢速度。