本文通过实验论证:Unixbench的Pipe-based Context Switching用例受操作系统调度算法的影响波动很大,甚至出现了虚拟机跑分超过物理机的情况。在云计算时代,当前的Unixbench已不能真实地反映被测系统的真实性能,需要针对多核服务器和云计算环境进行完善。
简单的说,视操作系统多核负载均衡策略的差异,该用例可能表现出两种截然不同的效果: 1、在惰性的调度策略环境下,测试得分较高,但是会导致系统中任务调度延迟,最终可能引起业务性能抖动。例如,在视频播放、音频处理的业务环境中,引起视频卡顿、音频视频不同步等问题。 2、在积极的调度策略环境下,测试得分偏低,但是系统中任务运行实时性更高,业务运行更流畅。
后文将详细说明Pipe-basedContext Switching用例的设计原理,测试其在不同系统中的运行结果,并提出测试用例改进建议。
1 测试背景近期,团队在进行服务器选型的时候,需要对两款服务器进行性能评估,其中一款服务器采用64核Xeon CPU,另一台则采用16核Atom CPU。详细配置信息如下:
根据硬件厂商的评测,Xeon服务器的综合性能是Atom服务器的3倍。 我们采用了久负盛名的Unixbench性能测试套件,为我们最终的选择提供参考。 Xeon的性能碾压Atom是毋庸置疑的,毕竟Atom 更专注于功耗而不是性能,Atom服务器甚至没有3级缓存,并且StoreBuffer、Message Queue的深度更低,流水线级数更少。 出于业务需求,在整个测试过程中我们更关注单核的性能。为了排除软件的影响,两台服务器均安装Centos 7操作系统。 测试命令很简单,在控制台中执行如下命令: ./Run -c 1 -v 执行时间比较久,我们可以到一边去喝点烧酒。一杯烧酒下肚,神清气爽:-)可以看看结果是否符合咱们的预期:
总分整体符合预期:Xeon服务器单核性能是Atom服务器的2.36倍(1390/588.4) 但是,这里出现了一个异常,细心的读者应该已经发现:Pipe-based Context Switching测试用例的结果比较反常!从上表可以看出,无论是总分还是单项分数,Xeon服务器均远远超过Atom服务器。其中也包括Pipe Throughput这项用例。然而“Pipe-based Context Switching”这项指标显得有点与众不同:在这项指标中,Xeon服务器的优势并不明显,仅领先25%左右。 为了排除测试误差,我们反复进行了几次测试,均发现同样的规律。“Pipe-based Context Switching”项的分数差异并不明显,没有体现出Xeon服务器的性能优势。 这一问题引起了我们的兴趣,Unixbench这样的权威测试软件的结果居然和厂商宣称的出入这么大。为了找出原因,我们使用其他测试环境,进行了一系列的对比测试。首先,我们找了更多物理机进行对比分析。 1.1 物理机对比测试为此,我们使用另一组服务器进行对比测试,其型号分别为:HP ProLiantDL360p Gen8、DELL PowerEdge R720xd。配置如下:
分别在两台服务器的控制台中输入如下命令,单独对“Pipe-based Context Switching”用例进行测试: ./Run index2 -c1 得到该测试项的分数为:
测试结果与上面相似,硬件参数明显占优的DELLL跑分仅领先HP不到20%:-( 1.2 物理机VS虚拟机测试似乎陷入了迷途,然而我们一定需要将加西亚的信送到目的地,并且坚信“柳暗花明又一村”的那一刻终究会到来。 为此,我们使用三组云虚拟机来进行测试。这三组虚拟机配置如下:
这三款虚拟机与此前的物理机参数相差不大,如果不出意外的话,分数应当介于300~400之间。 然而测试结果出人意料,以至于笔者的镜片摔了一地:
特别令人吃惊的是:第二组虚拟机的测试分数,竟然是物理主机的1.5倍,并且是第一组虚拟机和第三组虚拟机的5.4倍。 1.3 单核和多核对比测试为此,我们认真分析不同系统中的CPU占用率。发现一个特点:在Pipe-based Context Switching用例运行期间,在得分高的环境中,两个context线程基本上运行在同一CPU上。而在得分低的环境中中,两个context线程则更多的运行在不同的CPU上。这说明:测试结果差异可能与Guest OS中的调度算法及CPU负载均衡策略有关。 我们不得不启用了排除法,先看单核和多核之间的差异。 为了验证猜想是否正确,我们临时修改了Guest OS中内核调度算法。修改原理是:在唤醒线程时,不管其他CPU核是否空闲,优先将被唤醒任务调度到当前CPU中运行。这样的调度算法,其缺点是:被唤醒任务将不能立即运行,必须等待当前线程释放CPU后才能获得CPU,这将导致被唤醒线程的实时性较弱。 经过测试,在打上了Linux内核调度补丁的系统中,Pipe-based Context Switching在虚拟机和物理机上 ,得分大大提升。实际测试的结果如下:
很显然,我们不能将上述补丁直接应用到生产环境中,因为该补丁会影响任务运行的实时性。因此我们将Linux内核调度补丁回退,并修改“Pipe-based ContextSwitching”测试用例的代码,强制将context线程绑定到CPU 0中运行,这样可以避免Guest OS中的调度算法及CPU负载均衡算法的影响。测试结果如下:
我们再次修改“Pipe-based Context Switching”测试用例的代码,强制将context线程分别绑定到CPU 0和CPU 1中运行,这样也可以避免Guest OS中的调度算法及CPU负载均衡算法的影响。测试结果如下:
可以看到,应用了新的“Pipe-basedContext Switching”补丁之后,所有测试结果都恢复了正常,离真相越来越近了。 2 原因分析: CPU拓扑差异导致Unixbench分数异常通过前面针对“Pipe-based Context Switching”单实例用例的测试,带给我们如下疑问: 为什么在该用例中,虚拟机B得分接近600,远高于虚拟机A、虚拟机C,甚至高于虚拟机A所在的物理机? 为了分析清楚该问题,我们分析了Pipe-based Context Switching用例, 这个用例的逻辑是:测试用例创建一对线程A/B,并创建一对管道A/B。线程A写管道,线程B读A管道;并且线程B写B管道,线程A程读B管道。两个线程均同步执行。 经过仔细分析,虚拟机A和虚拟机B在该用例上的性能差异的根本原因是:在虚拟机环境下,底层Host OS向Guest OS透传的cpu拓扑不同,导致虚拟机系统中的调度行为不一致, 最终引起很大的性能差异。其中虚拟机A是按照Host主机的实际情况,将真实的CPU拓扑传递给Guest OS。而虚拟机B的主机则没有将真实的物理主机CPU拓扑传递给Guest OS。这会导致虚拟机内所见到的CPU拓扑和共享内存布局有所不同。 在真实的物理服务器上,每个物理核会有各自的FLC和MLC,同一个Core上的CPU共享LLC。这样的CPU拓扑允许同一Core上的CPU之间更积极的进行线程迁移,而不损失缓存热度,并且能够提升线程运行的实时性。这个特性,更利于视频播放这类实时应用场景。 下图是虚拟机A和虚拟机B中看到的CPU视图: 拓扑结构的差异地方在LLC的共享方式,虚拟机A使用的拓扑结构与物理机一致,同一个Core内CPU共享LLC。而虚拟机B的配置是同一个Core内CPU不共享LLC。不共享LLC的场景下,Linux将每个CPU在LLC层次的调度域设置为空。这样,虚拟机B的Guest OS会认为同一物理CPU内的两个超线程是两个独立的CPU,处于不同的域之间(这与实际的物理机配置不一致),因此其负载均衡策略会更保守一些。唤醒一个进程时,内核会为其选择一个运行的目标CPU,linux的调度策略会考虑亲和性(提高cache命中率)和负载均衡。在Linux 3.10这个版本下,内核会优先考虑亲和性,亲和性的目标是优先选取同一个调度域内的CPU。虚拟机A共享LLC,所有的CPU都在同一个调度域内,内核为其选择的是同一调度域内的空闲CPU。而虚拟机B因为LLC层次的调度域为空,在进入亲和性选择时,无法找到同一个调度域内的其它空闲CPU,这样就直接返回了正在进行唤醒操作的当前CPU。 最终,在虚拟机B中,除了偶尔进行的CPU域间负载均衡以外,两个测试线程基本上会一直在同一个CPU上运行。而虚拟机A的两个进程会并发的运行在两个不同的CPU上。 这一特征下的运行时间轴如下: 虚拟机B场景引入的开销是唤醒和等待运行开销,虚拟机A场景引入的开销是唤醒和切换运行开销。 在正常的工作负载下面,进程运行的时间会远大于进程切换的开销,而Pipe-based Context Switching用例模拟的是一个极限场景,一个线程在唤醒对端到进入睡眠之间只执行很简单的操作,实际等待运行的开销远小于切换运行的开销。 此外,在虚拟化场景下,两种方式唤醒操作中也存在差异,在虚拟机A这个场景下,唤醒的开销也远大于虚拟机B场景中的唤醒开销。最终出现虚拟机B上该用例的得分远高于虚拟机A、虚拟机C,甚至高于物理机上的得分。 为了进一步验证我们的分析是否正确。我们在HOST OS中,分别向虚拟机A的GuestOS和虚拟机B的Guest OS按照不同方式传递CPU拓扑。测试发现:在同样的CPU拓扑结构下,二者的测试分数是一致的。换句话说,导致该项测试分数差异的原因,在于不同的HOST OS向Guest OS传递的CPU拓扑存在差异,进而导致Guest OS中任务调度行为的差异。
3 结论:Unixbench需要针对多核服务器和云环境进行优化unixbench的Pipe-based Context Switching用例受操作系统调度算法的影响比较大。视操作系统多核负载均衡策略的差异,可能表现出两种截然不同的效果: 1、在多核负载均衡策略不积极的系统中,测试线程更多的运行在同一个CPU中,线程之间的切换开销更低。因此测试得分更高,但是会导致系统中任务调度延迟。在实时性要求比较高的系统中,这会引起业务抖动。例如,在视频播放、音频处理的业务环境中,这可能引起视频卡顿、音频视频不同步等问题。 2、在多核负载均衡策略更积极的系统中,测试线程更多的运行在不同的CPU中,线程之间的切换开销更高。因此测试分值更低,但是系统中任务调度延迟更低,业务的性能不容易产生波动。 换句话说:当前的Unixbench已不能真实地反映被测系统的真实性能,需要针对多核服务器和云计算环境进行完善。 4 修改建议我们建议调整unixbench测试用例,将测试用例的线程绑定到Guest OS的CPU上。这样就可以避免受到Guest OS调度策略和CPU负载均衡策略的影响。具体来说,有两种方法: 1、将context1和context2两个线程绑定在同一个CPU核上面。这样可以反应出被测试系统在单核上的执行性能。 2、将context1和context2两个线程分别绑定到不同CPU核上面。这样可以反应出被测试系统在单核的执行性能,以及多核之间的核间通信性能。
(完) 'Linux阅码场'是专业的Linux及系统软件技术交流社区,Linux系统人才培养基地,企业和Linux人才的连接枢纽。 |
|
来自: kaller_cui > 《专业》