将晦涩难懂的技术讲的通俗易懂
分类: LINUX
2018-06-24 22:07:20
英特尔至强 E5-2600 v4在对外宣传时候号称“为云而生”的,除了其强大的性能和众多核心外,主要亮点就是Resource Director Technology(RDT)新技术的加入。使得其有理由宣称“为云而生”。
我们知道在一个虚拟化环境中,宿主机的资源(包括CPU cache和内存带宽)都是共享的。但是如果有一个消耗cache的应用快速消耗了L3缓存,或者一个应用消耗了系统大量内存带宽,那么如何保证其他虚拟机应用呢?如何限制这些“可恶”的邻居呢?
针对上诉问题,以前都是通过控制虚拟机逻辑资源来实现,但是调整的粒度实在太粗,针对处理器缓存这样敏感而稀缺的资源,几乎是无能为力的。为此英特尔推出了RDT技术,希望可以解决这个问题。
那么看下RDT到底是什么神奇技术。
RDT技术有其实有5个功能模块,分别是
Cache Monitoring Technology (CMT)缓存监测技术、
Cache Allocation Technology (CAT)缓存分配技术、
Memory Bandwidth Monitoring (MBM)内存带宽监测技术、
Memory Bandwidth Allocation (MBA)内存带宽分配技术、
Code and Data Prioritization (CDP)代码和数据分区技术。
5个模块可以分为监控和控制两大类,CMT和MBM为监控技术,而CAT、MBA和CDP为控制技术。
RDT允许OS或VMM来监控线程,应用或VM使用的cache/内存带宽空间。通过分析cache/内存带宽使用率,OS或VMM可以优化调度策略提高效能,使得高级优化技术可以实现。
配合这几个技术,OS能够知道应用使用了多少CACHE空间,内存带宽,从而给虚拟机的虚拟处理器分配真实的CPU资源。结合CMT和CAT,缓存可做到实时监测和使用,能够让处理器的资源向虚拟机中最重要、最紧迫的任务分配。CDP可以限制数据在LLC中的存储,从而将空间节省出来给代码存储。
我们用更加直观的图来说明一下:
在一个系统里面运行多个应用,会出现应用线程之间LLC争用导致中断响应时间变长、性能吞吐量变小、高优先级进程资源被挤压等。
使用RDT后可以将LLC资源进行分配隔离,相互之间不会在出现争用。
目前的至强 E5-2600 V4(BDW平台)做到了对缓存的分配使用也即是CAT和CMT,并加入了对内存带宽的监测(MBM)。但是V4平台MBA技术是还没有实现的
Intel原计划是在下一代purley中实现,但是却在Purley 平台中出现对外宣称不支持,怪哉?。
下面我们来看下RDT的一个具体功能。以下方截图来说明,如下:
我们可以发现cores 0-5关联到了RMID 47-42,进 行了每个核监控。提供了CMT/MBM数据,从数据中发现core[
下面介绍两个RDT引入的两个关键术语RMID和CLOS。
OS或VMM会给每个应用或虚拟机标记一个软件定义的ID,叫做RMID(Resource Monitoring ID),通过RMID可以同时监控运行在多处理器上相互独立的线程,注意这里是指应用线程而是不是硬件的core,这个是由根本差异的。每个处理器可用的RMIDs数量是不一样的,这个可以通过CPUID指令获取得到,RMID数量不一样意味着可以监控独立线程的数量会有差异,如果一个系统上运行过多的线程可能会导致不能监控到所有线程的资源使用。
此外线程可以被独立监控,也可以按组的方式进行监控,多个线程可以标记为相同的RMID。同一个虚拟机下的所有线程可以标记为相同的RMID,同样一个应用下的所有线程可以标记为相同的RMID。绑定RMID到线程的动作由OS/VMM来完成。
每个core上存在一个MSR (IA32_PQR_ASSOC),可以关联一个RMID(而一个RMID对应一个线程),该RMID就记录在这个MSR上,然后通过硬件监控资源使用率。其中CLOS用于资源分配后面再说。
因为RMID关联到了core,而应用线程关联到RMID。这样就开始监控线程的资源使用率了。那么监控的数据如何获取?
也是通过寄存器来实现,通过MSR (IA32_QM_EVTSEL) 选择寄存器中设置RMID和Event ID。
在软件设置了合理的RMID+Event ID后,硬件会查看指定的数据,并通过MSR (IA32_QM_CTR)返回。
其中E/U 位表示Error和Unavailable,当数据合法时不会设置这两个位。那么数据就可以被软件使用。
Intel官方文档中提示,后续RMID的含义会扩展,包含更多的资源监控。
这个里有个问题,就是如果线程发生调度到其他core,那么硬件core上的MSR (IA32_PQR_ASSOC)上所记录的RMID对应的线程并没有运行在本core上了,就会导致数据不准确了。所以希望OS/VMM支持,将RMID加入到应用线程状态结构体中,这样在线程切换的时候MSR (IA32_PQR_ASSOC)中RMID能自动更新,确保跟踪的正确性。
CAT中引入了一个中间结构叫做CLOS(Class of Service),可以理解为资源控制标签。此外每个CLOS定义了CBM(capacity bitmasks),CLOS和CBM一起,确定有多少cache可以被这个CLOS使用。
一个应用可用的cache是通过一组MSR(IA32_L3_MASK_n,其中n表示CLOS数量)来指定的。
然后资源空间掩码(CBM)来标记相对可用空间、重复读和隔离情况。如下图中CLOS 比CLOS使用更少的cache,可以理解为更低的优先级。图中CLOS[
前面讲述的是理论偏多,我们知道了RDT能干啥,接下去看下如何使用吧。
RDT使用分为两种方式,一种是直接将RMID绑定到硬件线程,然后将应用绑定到这些线程,第二种是使能OS/VMM调度(需要内核支持),在进程切换时候会自动将RMID进行更新,能够支持线程迁移。
我们使用Intel开源的工具来实现,不需要内核支持。通过这个软件包可以使用CAT,CMT,MBM,CDP功能。
工具软件下载链接如下:
解压后,执行make && make install即可,如果找不到动态链接库,那么需要指定下动态库位置如下:export LD_LIBRARY_PATH=/usr/local/lib
RDT工具软件包的主要工具是pqos,pqos运行在用户层,通过标准Linux接口来访问MSR寄存器。因为msr文件接口是被保护的,所以需要root权限运行。支持在每个core或线程上提供CMT和MBM,其中MBM包括本地和异地内。
监控core0-11的所有事件(本地内存带宽,异地内存带宽,LLC空间使用率)
pqos -m all:0-11
监控core0,2,6的LLC
pqos -m llc:0,2,6
监控core0-2的本地内存带宽,core3-5的异地内存带宽。
pqos -m "mbl:0-2;mbr:3,4,5"
监控core组的事件
pqos -m "all:[0-11];llc:[12,13,14];mbl:[15-17,20]"
监控虚拟机使用
假设一个主机运行3个虚拟机,每个虚拟机分配core如下:
VM0 - cores 0-2
VM1 - cores 3-5
VM2 - cores 6-8
监控每个虚拟机事件,可以如下运行
pqos -m "all:[0-2],[3-5],[6-8];"
输出入下,每一行表示一个虚拟机资源使用情况,我们可以方便看到每个虚拟机资源使用情况。
CORE IPC MISSES LLC[KB] MBL[MB/s] MBR[MB/s]
0-2 0.69 3k 1120.0 0.0 0.0
3-5 1.62 10k 3520.0 0.0 0.0
6-8 0.49 1k 1040.0 0.0 0.0
显示当前资源分配配置
pqos -s
设置COS 1到前4个cache ways,设置cos 2到接下去8个cache ways.
pqos -e "llc:1=0x000f;llc:2=0x0ff0;"
设置COS1到所有SOCKETS,COS2到SOCKET 0和1,COS3到SOCKET 2和3.
pqos -e "llc:1=0x000f;llc@0,1:2=0x0ff0;llc@2-3:3=0x3c"
设置core0,2,6,10到COS1,core1到COS 2.
pqos -a "llc:1=0,2,6-10;llc:2=1;"
使用/禁用L3 CDP
pqos -R l3cdp-on
pqos -R l3cdp-off
使用L3CDP设置,设置cos 1代码和数据位。
pqos -e "llc:1d=0xfff;llc:1c=0xfff00;"
宿主机运行3个虚拟机,每个虚拟机分配3个core和不同优先级如下:
VM0 - cores 0-2 (P5)
VM1 - cores 3-5 (P2)
VM2 - cores 6-8 (P1)
VM0有最高优先级分配独立的8个LLC way. VM1分配6个,VM2分配4个,其中VM1和VM2共享2个way.
首先设置3个CLOS掩码位如下:
pqos -e "llc:1=0x00ff;llc:2=0x3f00;llc:3=0xf000;"
然后将CLOS关联到VM运行的cores上。从而可以限制VM的cache使用。
pqos -a "llc:1=0-2;llc:2=3-5;llc:3=6-8;"
设置COS 1可使用50%,设置COS 2可使用70%:
pqos -e "mba:1=50;mba:2=70;"
设置COS 1运行在所有SOCEKTS上,COS 2运行在SOCEKT 0和1上,COS3运行在SOCKET 2和3上:
pqos -e "mba:1=80;mba@0,1:2=64;mba@2-3:3=85"
注意平台,如果在BDW平台上测试,应该是不能使用的。
上面是传统的通过MSR方式来使用RDT,还可以通过操作系统内核的方式来使用RDT,这也是我们业务上常用的方式,不过需要内核支持
a)确认kernel和CPU均支持CAT
cat /proc/cpuinfo | grep cat_l3
b)开启resctrl
系统不会自动开启resctrl的用户接口,需要手工开启:
mount -t resctrl resctrl /sys/fs/resctrl
c)创建LLC策略
创建一个新的LLC分配策略#mkdir /sys/fs/resctrl/ptest
d)配置LLC策略
修改LLC分配策略,这里分配测L3 cache策略是1个cache way.
echo "L3:0=1” > /sys/fs/resctrl/ptest/schemata
e)绑定进程
绑定一个LLC策略到进程,假定PID=10101:
echo 10101 > /sys/fs/resctrl/ptest/tasks
这样就将10101的进程LLC资源限制在了1个cache way上而不能使用更多。
下面列出了传统MSR方式和Kernel方式使用RDT的差异:
支持CMT 调度级别 系统依赖
Kernel 否 进程 需要内核支持
MSR 是 Core 需要pqos工具
RDT提供的功能使得云端应用能够更为方便的获取硬件底层资源,用户可以制定更为满意的服务质量体系,并可以设定更为实际的云平台服务等级协议等,对当前云应用具有相当重要的商业意义。