1. LLC隔离的工具和原理
LLC是指Last Level cache,目前来说通常也就是L3 Cache,CAT是指Intel架构提供的一组工具&技术,用以支持LLC隔离。隔离的目的是针对Latency sensitive服务程序,提高QoS。可以考虑到两个LS敏感的程序跑在同一个机器上相互影响的程度还是比较大。
相关的一些资料如下:
- x86: Intel Cache Allocation Technology support
- Intel 64 and IA-32 Architectures Software Developer Manuals
其中的 17.16 PLATFORM SHARED RESOURCE CONTROL: CACHE ALLOCATION TECHNOLOGY
cpu cache隔离技术的原理基本上就是通过划分LLC,限制进程能使用的cache,前后隔离效果如下:
Cache Allocation Technology Allocates More Resource to High Priority Applications
1.1. Intel CAT技术
Intel CAT技术提供一系列工具:
- 通过CPUID指令,查询当前cpu架构是否支持CAT技术,以及支持哪些资源类型(目前来看一般就是LLC),同时可以查询CLOS的数量以及CBM,CBM是指bitmask的长度
- 提供一种机制,可以关联CLOSID和bitmask
- 提供一个特殊的寄存器,存储CLOSID,硬件根据CLOSID决定当前使用哪些资源
1.1.1. 内核隔离的实现原理
从内核提交的patch来说,目前的做法基本上是这样的:
- 新增一种cgroup文件系统,cacheqe,在进程组级别上控制。
- 用户通过cacheqe设置当前进程组使用哪些cache,不同的cgroup之间的cache可以是完全隔离的,也可以是共享的。
- 进程在schedule()的时候,内核讲当前进程的CLOSID设置到寄存器。
到这里内核以及用户态需要做的事情就完毕了。CPU在执行的指令的时候,就能根据寄存器的值来限制进程只能使用哪些cache。
但是有一点需要注意的是,Intel开发手册里提到,cache的设置必须是连续的,不能间隔的使用。比如一个24路的cache,只能类似于3,4,5这样设置,不能3,6,7这样设置(可能是硬件实现复杂度比较高,不允许这么玩)
1.1.2. CAT隔离的类型
CAT技术支持两种方式的LLC隔离,一种是overlap方式的,一种是isolate方式的,默认情况下,进程能够使用的所有的cpu cache,如下:
overlapped方式隔离:
其中:
- COS0可以访问所有的cpu cache
- COS1只能够访问M0~3,总共4路cache
- COS2只能够访问M0~1,总共2路cache
- COS3只能够访问M0,总共1路cache
也就是说,overlapped方式的隔离允许一部分cache被不同的${COS_ID}使用的,例如COS0~3都可以使用M0的cache
isolated方式隔离:
其中:
- COS0只能够访问M4~7,总共4路cache
- COS1只能够访问M2~3,总共2路cache
- COS2只能够访问M1,总共1路cache
- COS3只能够访问M0,总共1路cache
在isolated的方式,不同的COS之间只能使用独立的cache,不能相互使用
1.2. Intel CMT技术
xx
1.3. Intel MBM技术
xx
1.4. PQos工具
从上面我们能看到,通过内核打PATCH的方式来实现LLC隔离是很完美的。但是针对公司内,升级内核本身就是一个非常漫长的过程。因此,有必要提供一种不依赖于内核的用户态的方式来完成LLC隔离。这个工具就是Intel提供的PQos工具,作为一种不依赖内核、纯用户态实现的LLC隔离。但是这个工具的使用是很受限的
内核方案:
优点:完美支持cgroup控制
缺点:需要升级内核
PQos方案:
优点:纯用户态实现,不依赖内核升级
缺点:仅仅支持按照按照CPU Core绑定LLC,不支持进程组绑定LLC。也就是,PQos只能实现哪些CPU使用哪些LLC资源,而不能实现哪些进程组使用LLC资源。因为这个实现主要是依赖内核调度器来完成的
2. LLC隔离测试
2.1. 基于PQos的LLC隔离实验
考虑LLC自身的属性,以及在线服务的特点:时延敏感,我们选取Redis来作为测试对象。实验方法很简单,首先为了规避CPU自身对时延因此影响,我们把redis程序和干扰程序分别跑在不同的核心上,然后通过pqos工具进行LLC隔离,观察LLC在完全隔离、混部的场景下对在线服务时延的影响。具体实验过程分为三种:
- 单独运行Redis服务,观察Redis服务的时延
- 运行Redis服务和干扰程序,观察Redis服务的时延
- 运行Redis服务和干扰程序,开启LLC隔离,观察Redis服务的时延
干扰程序的选取,干扰程序只需要做到频繁的擦写cache即可,也就是说尽可能的避免Redis从LLC上读取数据,应该尽可能的触发Redis从内存上读写数据。
其中:
- newtest-solo-0xf, newtest-solo-0xff, newtest-solo-0xfff是在单独Redis服务,不开启干扰程序,通过逐步提高Redis进程可用的LLC总资源量,观察到的对时延的影响
- newtest-pollution-0xff 是同时运行Redis进程以及干扰程序,Redis和干扰程序分别各自占用一半的cpu核心,不开启LLC隔离的情况下观察到的时延数据
- newtest-simul-0xff 是同时运行Redis进程以及干扰程序,Redis和干扰程序各自占用一半的cpu核心,各自占用一半的cache,观察到的时延数据
从实验结果我们能够看到:
- 随着分配的LLC的增大:0xf -> 0xff -> 0xfff,时延有所改善
- 干扰程序运行 & 不开启LLC隔离的情况下,时延有所升高
- 干扰程序运行 & 开启LLC隔离的情况下,时延没有太大的变化