对于片上多核处理器,如何在多线程间公平有效地分配调度有限的共享资源是一个很重要的问题。随着处理器核规模的增长,多线程对于系统中有限的共享资源的争夺将愈发激烈,由此导致的对于系统性能的影响也将更加显着。为了缓解乃至解决这一问题,除了增加可用共享资源外,一个能够公平有效地在多线程间分配共享资源的调度算法也至关重要。在各类共享资源中,对于系统性能有着最大影响的是共享缓存和DRAM 系统。对于共享缓存,可以通过缓存分区,来降低由于线程间的争夺所带来的影响;对于DRAM系统,可以采取适当的调度算法来调节各个线程发出的访存请求的服务优先级,从而改善系统性能。首先分别以系统吞吐量和公平性为优化目标介绍了一系列对共享缓存的分区调度算法,并针对缓存分区粒度过大的问题给出了相关解决方案。然后从利用线程的访存行为特征和借鉴网络路由算法等多个角度介绍了DRAM 的调度算法。接下来,研究了从全局出发的联合调度算法,以解决针对不同共享资源的调度算法间相互矛盾的问题。最后,从不同角度对于今后的研究进行了展望。
引言
随着集成电路工艺的发展,片上多核处理器(Chip multi-processor, CMP)开始占据市场,在一个CMP 上并发地执行多个线程成为主流趋势。CMP上的多个核/线程通常共享最后一级缓存(lastlevel cache,LLC)、DRAM 控制器、主存总线带宽和预取部件(prefetching hardware)等多种资源。
系统中的共享资源总是有限的,线程间需要争夺共享资源的使用权。不同的线程其程序特征(在本文中主要指访存行为)存在差异,而线程争夺共享资源的能力通常与此相关。如果没有特别的调度机制,某些线程可能占用大部分乃至全部的系统资源,导致其他线程的请求得不到服务,最终对系统的性能(吞吐量和公平性)造成影响。
如果存在一个调度策略能够在多个并行线程间公平有效地分配共享资源,则可以缓解由于对共享资源的争夺所带来的负面影响,从而改善系统性能。
因此,在CMP 系统中对共享资源的分配调度成为一个值得研究的热点问题。
在CMP 系统中,最为重要的共享资源是其共享存储系统(主要包括共享缓存和主存带宽)。当线程的访存请求得不到服务时,由于所需数据没有及时返回,相关处理器核将会一直处于阻塞等待状态,导致计算资源的浪费,对系统性能会造成巨大影响。
学术界当前的研究重点也主要集中在共享缓存和主存带宽的分配调度上,因此,本文将从这两个方面对CMP 系统的共享资源调度问题进行阐述。
当私有缓存空间不够用时,程序将访问共享缓存,线程间会争夺有限的共享缓存空间。常用的最近最少使用替换算法(least recently used,LRU)不区分访存请求来自哪个线程,同等对待所有访存请求,当需要发生缓存替换时,总是逐出最近访问频率最低的缓存块。因此,多个线程实际上是在自由竞争共享缓存空间的使用权。一些能够快速产生大量缓存失效的线程可能替换掉其他线程的有效数据,独占大部分乃至全部缓存空间。缓存空间在线程间的分配方式不当会导致部分线程或总的缓存失效率急剧上升,影响到系统的性能。现有的研究大多通过缓存分区来解决这个问题。由于不同线程在不同的时刻对缓存空间的需求并不一样,简单地将共享缓存平均分给各个线程并不能有效解决问题。
制定相应的分区策略,根据程序运行中的动态特征把缓存空间适当分配给各个线程,从而尽量避免线程间对缓存的争夺,同时满足线程各自的缓存需求,从而改善系统性能。基于这种动态缓存分区的概念,学术界为改善系统性能,分别以提高系统吞吐量和改善系统公平性为优化目标提出了各类缓存分区策略。
当发生最后一级缓存失效时,访存请求需要读写主存,即动态随机存储器(dynamIC random-aCCessmemory,DRAM),而DRAM 的访存带宽是有限的。来自不同线程的访存请求间存在相互依赖和制约的关系,延时情况会由于线程间的干扰(interface)加剧,进而导致带宽利用率低。任由多个线程自由争夺有限的访存带宽,会降低系统性能。通过DRAM控制器充分利用DRAM 的结构特点和线程的访存行为特征对访存请求的服务优先级进行合理的调度可以降低延迟,提高带宽利用率,进而改善系统性能。因此,学术界对于多线程环境中的有效访存调度策略也进行了大量研究。
单独针对一类共享资源各自提出调度策略,从全局效果来看可能相互矛盾,达不到优化目的。因此,在一些关于共享资源调度策略的研究中,需要综合考虑各类共享资源,进行联合调度。
为了深入理解CMP 系统中共享资源的分配调度策略、存在的问题以及应用前景,以便更好地应对随着CMP 系统规模增大而带来的调度复杂度,对CMP 系统中共享资源的分配调度策略进行综述是具有重要意义的。本文首先介绍了基于缓存分区的共享缓存分配调度策略的基本思想和特点,然后介绍了采用不同性能优化目标的缓存分区方案的研究进展,接下来我们研究了DRAM 的访存调度算法,之后对于系统中多种共享资源的联合调度算法进行了介绍。最后,对CMP 系统中共享资源的分配调度策略未来可以开展的研究方向进行了展望。
1 基于缓存分区的分配调度策略概述
1.1 缓存分区的背景
在CMP 系统中,一级缓存通常是私有的,而最后一级缓存(last level cache,LLC)则在各个核间共享(下文提到的缓存如无特别说明都是指LLC)。
共享缓存使得多个线程可以共享某些数据,降低通讯延迟,同时减少数据的冗余备份,提高缓存空间利用率。但是,线程间对于有限共享缓存空间的争夺,也会导致缓存失效率的上升,影响系统的吞吐量和公平性。
在单核单线程处理器中最为常用的缓存替换算法是LRU.LRU 不区分访存请求的线程来源,同等对待所有访存请求,每次发生缓存失效时替换最近最少访问的缓存块。LRU 在单线程环境中能够有效地提高缓存利用率。然而,在多线程环境下,由于线程间对于共享缓存空间的争夺,仍然采用LRU 算法的话,一个频繁发生缓存失效的线程(例如,流媒体应用)会不公平地替换掉其他线程的有用数据块,占用大量乃至全部缓存空间,从而导致其他线程的缓存失效率(MiSSRate)①大幅上升,破坏系统的公平性;另外,一个产生大量缓存失效的线程,其数据的复用率(reused)可能很低,而其他线程被替换掉的却可能是一些常用数据,从而降低了共享缓存的利用率,导致总的缓存失效率上升。无论哪种情况,最终结果都会使得系统的性能受到严重影响。
1.2 缓存分区的基本思想
为了降低线程间争夺缓存空间带来的影响,一种直观的想法是对缓存进行分区,通过明确地把缓存空间分配给各个核来避免线程间的干扰。一旦某部分缓存被划分给某个线程,由该线程独享这部分缓存空间,其他线程无权替换这部分缓存空间中的数据,避免了由于缓存争夺所带来的额外缓存失效,使得所有线程的请求都能够得到合理服务。缓存分区之后,对单个线程而言,相当于运行在单线程环境中一样,因此,在各缓存分区内可以仍然采用LRU算法。
最简单也最容易实现的的缓存分区方式是在程序运行前将缓存平均划分给CMP 系统中的各个核,称之为静态分区。但这种做法的缺点是明显的,不同线程对于缓存空间需求不一样,并且即使同一个线程在不同的执行阶段对缓存空间的需求也可能不一样,而静态分区策略不能有效反映这种情况。部分线程可能划分到超出需求的缓存空间,导致缓存空间的浪费,而另一部分线程对于缓存空间的需求却没有得到满足。静态缓存分区策略实际上是把二级缓存当做了各个处理器的一级私有缓存的扩充,失去了多核共享缓存所能带来的好处。近年来的大量研究中都不再采用静态分区策略。
1.3 动态缓存分区
显然,只有知道各线程的具体访存行为特征和缓存需求,才能作出最优的缓存分区决策。制定一个公平有效的缓存分区策略,需要一个明确的性能优化目标,并且根据线程所处的具体执行环境与执行阶段,充分利用线程访存行为的动态特征。在共享缓存分区中用到的程序动态特征一般指线程在划定不同大小的缓存空间下所对应产生的缓存失效率。
动态缓存分区策略的优化目标一般包括两类,吞吐量和公平性。吞吐量是针对系统的整体性能而言。对于动态缓存分区策略,一个常用的评估吞吐量的指标是共享缓存产生的总缓存失效率,通过最小化缓存失效率达到最大化系统吞吐量的目标;同时,缓存失效率低,意味着处理器核等待数据返回的阻塞等待时间减少,提交指令的速度更快,因此,另一个与系统吞吐量相关的指标是IPC(instructiONsper cycle)。公平性则是指系统中并行运行的多个线程能够公平的使用共享缓存,不会存在某些线程占有大部分缓存空间,导致其他线程的缓存失效率大幅增长,性能受到重大影响;公平性同时关注系统中的每个线程,尽量保证所有线程的服务质量得到同等程度的改善。
基于不同的性能优化目标,提出的缓存分区策略通常有很大分别。Hsu 等人在其相关研究中即根据优化目标的不同,命名了3 类调度策略:第1类缓存调度策略可称为“capitalist”,该类策略对于各线程的访存请求无限制,任其自由争夺共享资源,“适者生存”,最为常见的即为通用的LRU 替换策略,但是这类调度策略在多线程环境下通常对于系统的吞吐量和公平性都有影响;第2 类是以最大化系统吞吐量为优化目标的“utilitarian”,该类策略忽视公平性,无法保证单个线程的性能表现;最后一类是以系统公平性为目标的“communist”,该类策略尽量确保并行执行的各线程的服务质量得到同等程度的改善,不会有某些线程的性能受到严重影响。