PLINQ并行开发中常见性能问题及应对方案
创始人
2024-06-14 13:20:53
0

在上月举行的PDC 09大会上,微软并行库团队的开发工程师Igor Ostrovsky介绍了PLINQ的工作原理,以及多核编程中,尤其是在PLINQ使用过程中几种常见性能问题及应对方法。Igor表示,这些性能问题很少在顺序编程中遇到,因此在并行环境中容易被人忽视。

#T#

第一个性能问题是内存分配

由于利用了多核CPU进行运算,对象分配的速度也加快了。此外,程序中可以还会出现更高频率的字符串连接或装箱操作,这都会使GC压力增大。.NET应用程序所使用的默认GC方式为Concurrent GC,它的性能很高,并且为降低应用程序的延迟作了很多优化。它的最佳使用场景是用户交互式应用,这样可以尽可能避免用户界面的停顿,但是它在长期运行的多核程序中表现并不好。而最终的结果是大量计算时间耗费在GC上,此时应用程序算法即便是利用了多个核,也会发现它的伸缩能力受到了GC限制。解决这个问题的方法之一是减小内存分配,例如可以使用值类型来代替引用类型。值类型的对象会分配在线程栈而不是堆上,以此避免对GC产生压力。第二个方法是在config文件中启用Server GC。使用Server GC会改变.NET分配对象的方式,此时.NET会为每个核准备不同的堆,并且独立进行垃圾回收。这样在一台4核的机器上便可以有4个线程同时进行垃圾回收,性能自然也就随着多核而提升了。

第二个性能问题是CPU在局部化(Locality)和缓存方面的问题

在流行的多核架构中,每个核都有独立的二级缓存。CPU并不会缓存单个地址中的数据,而是缓存以64字节或128字节相邻内存的缓存条目(cache line),因此当某个核改变了内存中的数据时,则其他核中地址相邻的缓存数据也会失效,这样CPU每次进行计算时都要从速度较慢的内存中加载数据。这个性能问题的隐蔽之处在于代码中的不同数据——例如同一个数组的不同下标——可能在内存中处在同一个缓存条目中,因此这个问题又被称为错误共享(False Sharing)。Igor演示了一段性能低下的代码,在这个实现中多个线程会不断读写同一个数组的相邻下标,因此造成了错误共享。Igor的修改方法是将数据存放在数组中相距较远的下标,甚至是不同的数组中。由于CPU的缓存条目大小有限,这种方法可以避免出现错误共享。博客园老赵在《计算机体系结构与程序性能》一文中也提出了一种优化方式,他的做法是尽可能使用局部变量来保存计算过程中的中间值,以此减少对数组的修改操作。由于局部变量分处不同线程的栈空间内,因此地址相距很远,不会造成错误共享问题。当有人问起到这种优化方式是否安全时,Igor答到,这其实和CPU架构的实现方式有很大关系。如果某一天缓存实现变化了,可能这种优化方式会适得其反。不过在目前主流架构中,这样的做法是比较安全的。Igor补充道,他认为这也是为什么“全自动”并行化那么困难的原因之一,因为在并行环境下影响程序性能的方面实在太多了。

第三个问题在于开发人员倾向于在PLINQ中使用大量小粒度的委托来完成工作

此时每个委托的计算任务很小,而委托的执行次数会很多。在计算较长的序列时,小粒度的委托对象也能获得性能提高,但是它会产生额外的负载。例如,MoveNext和Current的调用,以及每个委托的执行性能都和虚方法比较接近。此外,一个较长的输入序列也会受限于内存的吞吐量。因此,Igor建议开发人员在使用PLINQ时尽可能使用计算量较大的委托,以此减少计算主体外的性能开销。

第四和第五问题则与PLINQ的实现有关

Igor表示,PLINQ可以并行执行所有的LINQ查询,但是相对于复杂的LINQ查询,PLINQ能够对简单的LINQ操作有更好的优化。因此,Igor建议开发人员在使用PLINQ时可以手动将复杂的LINQ表达式拆分为简单的LINQ查询,并且只在真正需要大量计算的地方才开始并行化。这种结合顺序执行和并行执行的方式,可以让应用程序的性能达到最优。此外,为不同的输入方式选择不同的分块(partition)策略对性能的影响很大,因此PLINQ会对数组和IList<>进行静态的分割,而对IEnumerable<>集合按实际需求进行划分,而开发人员也可以通过自定义Partitioner的方式来指定特别的分割策略。

最后,Igor强调,使用并行计算进行程序性能优化之前,一定要通过合适的评测方式来找到代码的瓶颈。如果这个瓶颈正符合数据并行(data parallel)模式,那么可以使用PLINQ进行性能优化。而优化完成后还需要评测其效果,并使用之前提出的几种方案进行合适的调整。

PLINQ地位图

延伸阅读

PLINQ(Parallel LINQ)。微软对PLINQ在Parallel FX中的定位是:PLINQ是TPL(Task Parallel Library)的一个高层应用。目前PLINQ已经被集成到.NET 4.0当中了。

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...