初识 PLINQ

近几年 Microsoft 推出的并行计算编程模型,PLINQ 要占到中心位置。LINQ 是语言集成查询(Language-Integrated Query )的缩写,.NET 框架 3.5 的新特性,它试图在对象领域和数据领域之间架起了一座桥。传统上,数据是SQL的天下,而面向对象语言(如Java,C#等)在编程语言领域称雄,二者之间的沟通很费周章,在编程语言里拼接SQL字串不仅繁琐,而且还容易产生安全漏洞。这时,LINQ出现了,它说:“查询要是语言的一部分!”

具有 Intellisense 的 LINQ 查询

PLINQ 是 LINQ 的并行扩展,是 .NET 框架 4.0 的一部分,它的台词是:“程序员写LINQ查询,之后的并行化有我!”

它的重要性来自一下几点:

1. 自2005年以来,摩尔定律失效,单个CPU性能提升有限,多核成为趋势,提高并行程序设计的效率成为对平台提供者来说很紧急的问题。

2. 两种高级并行性:数据并行与任务并行的竞争决出了结果。多年任务并行(多线程及其它)的实践证明了并发复杂性无法有效控制。而数据并行随着Google的MapReduce算法的倍受推崇而得到公认:“Many-Core 时代并行与分布式计算的解决之道”。

3. PLINQ是挖掘数据并行性的解决方案,这种设计是因为数据并行性的众望所归。

下面这个图简要讲解了 PLINQ 的原理:并行任务数和分配方式由数据分割决定的,也就是数据的特性决定并行计算的方式:

image

数据源最好IList,这样数据分割效率更高。

 

下面是“判断100000000后100000个自然数是否为素数”的例子:

三种实现方法的比较static int[] arr = Enumerable.Range(100000000, 100000).ToArray();

        static void Main(string[] args)
        {
            Utils.Measure("Sequential", () =>
                {
                    bool[] results = new bool[arr.Length];
                    for (int i = 0; i < arr.Length; i++)
                    {
                        results[i] = Utils.IsPrime(arr[i]);
                    }
                });

            Utils.Measure("LINQ", () =>
            {
                bool[] results = arr.
                    Select(x => Utils.IsPrime(x)).
                    ToArray();
            });

            Utils.Measure("PLINQ", () =>
            {
                bool[] results = arr.AsParallel().AsOrdered().
                    Select(x => Utils.IsPrime(x)).
                    ToArray();
            });
        }

上述代码用到了两个辅助方法(判断素数和计时):

辅助方法class Utils
    { 
        public static void Measure(string name, Action func)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            func();
            stopwatch.Stop();
            Console.WriteLine("-------------------------");
            Console.WriteLine("      " + name);
            Console.WriteLine("      Time: " + stopwatch.ElapsedMilliseconds + " ms");
            Console.WriteLine("-------------------------");

        }

        public static bool IsPrime(long x)
        {
            if (x <= 2) return x == 2;
            if (x % 2 == 0) return false;

            long sqrtx = (long)Math.Ceiling(Math.Sqrt(x));
            for (long i = 3; i <= sqrtx; i++)
            {
                if (x % i == 0) return false;
            }
            return true;
        }
    }

在双核机器上执行的结果:

PLINQ_Result

可见LINQ 与简单的顺许方法性能相当,而PLINQ大致得到线性加速比!

细心的朋友可能已经注意到了,上述例子中数据源是在内存里的。如果要支持更多类型数据源,比如SQL Server,则需要相应的 LINQ Provider,比如:

http://www.sheltonblog.com/archive/2008/07/11/list-of-linq-providers.aspx

 

转载于:https://www.cnblogs.com/foamliu/archive/2009/12/31/1636919.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值