Linux多核并行编程关键技术

来源:wahaha02 发布时间:2018-06-29 11:26:41 阅读量:1303

  在摩尔定律失效之前,提升处理器性能通过主频提升、硬件超线程等技术就能满足应用需要。随着主频提升慢慢接近撞上光速这道墙,摩尔定律开始逐渐失效,多核集成为处理器性能提升的主流手段。现在市面上已经很难看到单核的处理器,就是这一发展趋势的佐证。要充分发挥多核丰富的计算资源优势,多核下的并行编程就不可避免,Linux kernel就是一典型的多核并行编程场景。但多核下的并行编程却挑战多多。

  目前主流的计算机都是冯诺依曼架构,即共享内存的计算模型,这种过程计算模型对并行计算并不友好。下图是一种典型的计算机硬件体系架构。

  这种架构中,有如下设计特点:

  ·多级cache改善CPU访问主存的效率;

  ·store buffer模块改善cache write由于应答延迟而造成的写停顿问题;

  外设DMA支持直接访问主存,改善CPU使用效率;

  cache一致性问题由cache一致性协议MESI解决,MESI由硬件保证,对软件来说是透明的。MESI协议保证所有CPU对单个cache line中单个变量修改的顺序保持一致,但不保证不同变量的修改在所有CPU上看到的是相同顺序。这就造成了乱序。不仅如此,乱序的原因还有很多:

  ·invalidate queue引起的延迟处理,会造成乱序;

  ·分支预测、多流水线等CPU硬件优化技术,会造成乱序;

  这种情况造成,就连简单的++运算操作的原子性都无法保证。这些问题必须采用多核并行编程新的技术手段来解决。

  锁技术

  ·自旋锁,不休眠,无进程上下文切换开销,可以用在中断上下文和临界区小的场合;

  ·互斥量,类似与信号量,但只支持同时只有一个并发体进入临界区;

  ·顺序锁,支持读并发,写写/读写间互斥,写会延迟读,对写友好,适用写侧重场合;

  ·按统一的顺序使用锁(锁的层次),解决死锁问题;

  ·范围锁(树状锁),解决锁惊群问题;

  原子技术

  ACCESS_ONECE():只限制编译器对内存访问的优化;

  smb_wmb():写内存屏障,刷新store buffer,同时限制编译器和CPU的乱序优化;

  smb_mb():读写内存屏障,同时刷新store buffer和invalidate queue,同时限制编译器和CPU的乱序优化;

  多提一句的是,atomic_inc()原语为了保证原子性,需要对cache进行刷新,而缓存行在多核体系下传播相当耗时,其多核下的并行可扩展性差。

  上一小节中所提到的原子技术,是无锁技术中的一种,除此之外,无锁技术还包括RCU、Hazard pointer等。值得一提的是,这些无锁技术都基于内存屏障实现的。

  RCU适用的场景很多,其可以替代:读写锁、引用计数、垃圾回收器、等待事物结束等,而且有更好的并行扩展性。但RCU也有一些不适用的场景,如写侧重;临界区长;临界区内休眠等场景。

  数据分割技术

  ·数组

  ·基树(Radix Tree)/稀疏数组

  使用这些便于分割的数据结构,有利于我们通过数据分割来改善并行可扩展性。

  ·读写分割:以读为主的数据与以写为主的数据分开;

  ·专项分割:把经常更新的数据绑定到指定的CPU/线程中;

  4种分割规则中,所有权分割是分割最彻底的。

<p white-space:normal;background-color:#ffffff;"="" style="word-wrap: break-word; margin-top: 0px; margin-bottom: 0px; padding: 20px 0px 0px; font-family: 宋体, Arial; white-space: normal; background-color: rgb(255, 255, 255); color: rgb(51, 51, 51); word-break: break-all; line-height: 2;">  以上这些多核并行编程内容基本上涵盖了Linux kernel中所有的并发编程关键技术。当然并行编程还有很多其他技术没有应用到Linux kernel中的,如无副作用的并行函数式编程技术(Erlang/Go等)、消息传递、MapReduce等等。


原文链接:https://www.cnblogs.com/wahaha02/p/9175637.html


标签: 服务器搭建
分享:
评论:
你还没有登录,请先