Linux调度器免锁优化方法研究

作者:张旭;顾乃杰;苏俊杰; 刊名:小型微型计算机系统 上传者:蒋文娟

【摘要】Linux操作系统被广泛用于各领域,多核环境下Linux调度器依靠自旋锁保证其正确运行,这给调度器带来了严重的锁竞争.在分析Linux调度器的基础上,对其提出三个层次的免锁优化方法:基础优化、调度行为优化和基于上层应用特征的参数调优.基础优化尝试从代码层面直观地缩小程序的锁冲突域;调度行为优化针对进程创建过程中的唤醒操作提出了一种新进程延迟唤醒方法,有效地减少了进程创建过程中的锁竞争;基于上层应用特征的参数调优可以在对内核修改很小的情况下完成调度器性能提升.

全文阅读

1引言随着多核处理器的普及,Linux操作系统在原来的调度器基础上增加了对多核处理器的支持,提出了调度域、负载均衡[1]等概念,用以提升系统在多核处理器上的性能.Linux使用CFS(CompletelyFairScheduler)调度器[2],每一个处理器核都有属于自己的调度信息和一个进程运行队列.在多核处理器上,调度并不仅仅在单个处理器核中进行,而是在多个核中异步地推进.如果每个处理器只能访问自己的调度信息和运行队列,而不知道全局的负载情况,难免会造成全局负载不平衡,进而导致处理器计算资源的浪费.内核中负载均衡模块就是用于平衡不同处理器核的工作负载的,但是这样需要破坏调度信息的局部性,允许不同的处理器核访问其他处理器核的资源.这种情况下,调度器中关键资源的访问冲突问题变得异常突出,而最核心的竞争资源就是进程运行队列.目前Linux内核主要通过使用自旋锁(spinlock)[2]来控制运行队列的并发访问.自旋锁语义直观,且使用方法简单,有利于程序开发人员使用.虽然自旋锁能够很好地对临界资源进行保护,但是CPU处于自旋状态时实际上是在做“无用功”,所以大量的锁竞争将严重影响调度器的执行效率和系统性能.免锁优化指在不改变程序正确性的情况下,通过代码调整或算法改进减少程序中出现的锁竞争.目前针对Linux调度器的研究主要是对调度算法或者负载均衡策略的改进[1,3,4],近年来则侧重于针对特定应用场景的调度算法的设计或改进,例如,旨在提升嵌入式系统电源使用效率的基于能耗的公平队列[5],以及用以实现自动化散热管理的基于热量自感知的调度算法[6].针对调度器的免锁优化研究还处于起步阶段,内核中常见的做法是通过细化锁粒度来提升系统的可伸缩行,即对于一个数据结构,需要标记其中各个独立的部分,使用多个锁来保护结构成员[7].这种方法可以一定程度提升系统性能,但是锁个数的增加造成锁操作开销增大,且多个锁的获取和释放顺序需要保证.与此同时,相关研究人员还提出了一些对自旋锁的改进方案,以适用不同的应用场景,如顺序锁[7]、RCU(Read-Copy-Update)机制[2]等.顺序锁为写者赋予了较高的优先级,即在有读者访问资源的时候依然允许写者继续进行.与顺序锁相似,RCU机制也是应用于读多写少的情况.RCU技术的核心是写操作分为写和更新两步,允许读操作在任何时候无阻碍的运行.考虑到原子操作的高效性[8],基于CAS(CompareandSwap)原语[9]的无锁编程技术[10]也是时下的研究热点,不过无锁编程技术需要解决垃圾回收[11]和ABA问题[8],为系统带来额外开销,而且基于CAS设计的无锁数据结构通常应用场景较小,使用较为困难.本文在分析Linux调度器的基础上,对其提出三种不同层次的免锁优化方法:基础优化、调度行为优化、基于上层应用特征的参数调优.其中基础优化是代码级的、以直观地缩小锁冲突域为目标的优化,不影响调度器本身的行为;调度行为优化针对进程创建过程中的唤醒操作,提出了一种新进程延迟唤醒方法,该方法将不能被立即唤醒的新进程放入延迟队列中,并为延迟队列创造“一个生产者一个消费者”的访问环境,并在此基础上通过循环数组和链表实现队列的免锁,避免了不必要的锁竞争;基于上层应用特征的参数调优以Web服务器为研究对象,根据Web服务器中服务进程的生命周期特征,调整调度器核心参数,达到减少锁操作的目的.实验表明,三种层次的优化都能不同程度地提升Linux调度器性能,其中调度行为优化效果较为明显,而基于上层应用特征的参数调优可以在对内核修改很小的情况下,提升应用

参考文献

引证文献

问答

我要提问