C#4.0入门 第二章 任务并行库—第二页 活用了内核吗?(转)


真的活用了内核吗?
对于想确定是不是真正地活用了内核的人,准备了如下的验证程序。这个程序为,把简单循环所花费的时间分两次进行计算。但是,第一次使用传统方法,第二次使用并行方法。


验证程序




 
using System;
using System.Threading.Tasks;
class Program
{
private const int count = 1000000000;
private static void taro()
{
Console.WriteLine("Taro is busy now");
for (int i = 0; i < count; i++)
;
Console.WriteLine("Taro Done");
}
private static void hanako()
{
Console.WriteLine("Hanako is busy now");
for (int i = 0; i < count; i++)
;
Console.WriteLine("Hanako Done");
}
static void Main(string[] args)
{
DateTime start1 = DateTime.Now;
taro();
hanako();
Console.WriteLine(DateTime.Now - start1);
DateTime start2 = DateTime.Now;
Parallel.Invoke(taro, hanako);
Console.WriteLine(DateTime.Now - start2);
}
}


上例的执行结果(执行debug?build,在双内核的CPU上运行。后半段中顺序可以颠倒。)




 Taro is busy now
Taro Done
Hanako is busy now
Hanako Done
00:00:05.9710000
Taro is busy now
Hanako is busy now
Hanako Done
Taro Done
00:00:03.0320000


如您所见,执行并行计算,只花了大约一半时间就结束了。正是因为把处理分散给两个内核,才能相差这么多时间。


另外,因为CPU是有限的资源,所以不应该只是为了等待而使用Thread.Sleep的方法,而是应该把没有利用的时间转交给其他的处理。

并行执行foreach语句

实际使用的时候,如果并行执行foreach语句或for语句,可以立刻提高性能。以下为将foreach语句与Parallel.ForEach方法进行比较的例子。


将foreach语句与Parallel.ForEach方法进行比较




 
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
int [] a = {1,2,3,4,5,6,7,8,9};
foreach (var n in a) Console.Write("{0} ",n);
Console.WriteLine("by serial");
Parallel.ForEach(a, (n) => Console.Write("{0} ", n));
Console.WriteLine("by parallel");
}
}


上例的执行结果(后半段中顺序可以颠倒。)




 1 2 3 4 5 6 7 8 9 by serial
1 2 3 4 6 7 8 9 5 by parallel


这里应该注意的是,Parallel.ForEach方法的执行结果与foreach语句的执行结果不一定相同。所以如果元素的顺序很重要的话,并行处理就不适合了。

并行执行for语句
对于数值的简单遍历循环,也可以用并行来处理。


并行执行for语句



 
using System;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++) Console.Write("{0} ", i);
Console.WriteLine("by serial");
Parallel.For(0, 10, (n) => Console.Write("{0} ", n));
Console.WriteLine("by parallel");
}
}


上例的执行结果(后半段中顺序可以颠倒。)




 0 1 2 3 4 5 6 7 8 9 by serial
0 5 1 2 4 8 9 3 6 7 by parallel


但是,并不是所有的for语句都可以用并行处理来实行。同时,do语句和while语句也不能采用并行处理。只有在循环开始前循环的次数已确定的情况下可以采用并行处理。因为所谓“并行”就是在判定为“循环结束”之前,首先要把将要执行的循环实现分配好。


基于同样原因,循环处理中如果有break语句退出循环,也不能采用并行处理。
posted @ 2011-06-11 16:00  董雨  阅读(180)  评论(0编辑  收藏  举报