介绍
我有两套机器,套餐A和套餐B,硬件/软件配置看似相同,但性能却存在显著差异。套餐B取决于速度快 4 倍比 A 组中的机器要多。然而,如果我重新启动 A 组中的一台机器,它莫名其妙地开始按预期运行,就像 B 组中的机器一样。我无法找到这种行为的解释。
硬件配置
- 英特尔
S2600KP
平台 - 双处理器
E5-2630v3
,8个物理核心,2.4GHz基本频率,3.2GHz睿频。 8x8GB RAM DDR4
,2133Mhz,每通道一个模块- 没有任何机器具有由 BMC 记录的可能指向硬件问题的 SEL 事件。
- 在整个基准测试期间,没有任何机器触发任何机器检查异常。
所有硬件组件的型号/零件编号均相同。
设置和软件
BIOS 版本和BIOS 设置是相同的,例如
HT
已启用,Turbo Boost
已启用。详情请参阅链接。这些机器运行的是与内核相同
64 bits
版本的。Red Hat 6
2.6.32-504
问题
两组中的机器都处于空闲状态,但无论我尝试运行何种负载,在性能方面都会得到截然不同的结果。为了简单起见,我将在核心 0 上运行所有基准测试。结果在所有核心(两个处理器)上均可重现。
套餐A
[root@SET_A ~]# uptime
11:48:40 up 51 days, 19:34, 2 users, load average: 0.00, 0.00, 0.00
[root@SET_A ~]# taskset -c 0 sh -c 'time echo "scale=5000; a(1)*4" | bc -l > /dev/null'
real 0m43.751s
user 0m43.742s
sys 0m0.005s
套餐B
[root@SET_B ~]# uptime
11:50:00 up 15 days, 19:43, 1 user, load average: 0.00, 0.00, 0.00
[root@SET_B ~]# taskset -c 0 sh -c 'time echo "scale=5000; a(1)*4" | bc -l > /dev/null'
real 0m18.648s
user 0m18.646s
sys 0m0.004s
观察结果
涡轮增压器
报告核心 0 处于C0 Consumption
状态,并且P0 Performance
在整个基准测试期间处于启用 Turbo Frequency 的状态。
套餐A
[root@SET_A ~]# turbostat -i 5
pk cor CPU %c0 GHz TSC SMI %c1 %c3 %c6 %c7 CTMP PTMP %pc2 %pc3 %pc6 %pc7 Pkg_W RAM_W PKG_% RAM_%
3.15 3.18 2.39 0 3.26 0.00 93.59 0.00 40 46 49.77 0.00 0.00 0.00 46.45 22.41 0.00 0.00
0 0 0 99.99 3.19 2.39 0 0.01 0.00 0.00 0.00 40 46 0.00 0.00 0.00 0.00 29.29 12.75 0.00 0.00
套餐B
[root@SET_B ~]# turbostat -i 5
pk cor CPU %c0 GHz TSC SMI %c1 %c3 %c6 %c7 CTMP PTMP %pc2 %pc3 %pc6 %pc7 Pkg_W RAM_W PKG_% RAM_%
3.14 3.18 2.39 0 3.27 0.00 93.59 0.00 38 40 49.81 0.00 0.00 0.00 46.12 21.49 0.00 0.00
0 0 0 99.99 3.19 2.39 0 0.01 0.00 0.00 0.00 38 40 0.00 0.00 0.00 0.00 32.27 13.51 0.00 0.00
简化基准
为了尽可能简化基准测试(没有 FP,尽可能少的内存访问),我编写了以下 32 位代码。
.text
.global _start
_start:
movl $0x0, %ecx
oloop:
cmp $0x2, %ecx
je end
inc %ecx
movl $0xFFFFFFFF,%eax
movl $0x0, %ebx
loop: cmp %eax, %ebx
je oloop
inc %ebx
jmp loop
end:
mov $1, %eax
int $0x80
.data
value:
.long 0
它只是将寄存器从 0 增加到0xFFFFFFFF
2 倍,没有其他操作。
套餐A
[root@SET_A ~]# md5sum simple.out
30fb3a645a8a0088ff303cf34cadea37 simple.out
[root@SET_A ~]# time taskset -c 0 ./simple.out
real 0m10.801s
user 0m10.804s
sys 0m0.001s
套餐B
[root@SET_B ~]# md5sum simple.out
30fb3a645a8a0088ff303cf34cadea37 simple.out
[root@SET_B ~]# time taskset -c 0 ./simple.out
real 0m2.722s
user 0m2.724s
sys 0m0.000s
4 倍差异增加寄存器。
使用简化的基准进行更多观察
在基准测试期间,两台机器的中断数量相同~1100 intr/s
(使用 mpstat 报告)。这些中断大多是本地计时器中断CPU0
,因此中断源基本上没有区别。
套餐A
[root@SET_A ~]# mpstat -P ALL -I SUM 1
01:00:35 PM CPU intr/s
01:00:36 PM all 1117.00
套餐B
[root@SET_B ~]# mpstat -P ALL -I SUM 1
01:04:50 PM CPU intr/s
01:04:51 PM all 1112.00
对于P-States
和,C-States
与上述相同。
性能分析
套餐A
Performance counter stats for 'taskset -c 0 ./simple.out':
41,383,515 instructions:k # 0.00 insns per cycle [71.42%]
34,360,528,207 instructions:u # 1.00 insns per cycle [71.42%]
63,675 cache-references [71.42%]
6,365 cache-misses # 9.996 % of all cache refs [71.43%]
34,439,207,904 cycles # 0.000 GHz [71.44%]
34,400,748,829 instructions # 1.00 insns per cycle [71.44%]
17,186,890,732 branches [71.44%]
143 page-faults
0 migrations
1,117 context-switches
10.905973410 seconds time elapsed
套餐B
Performance counter stats for 'taskset -c 0 ./simple.out':
11,112,919 instructions:k # 0.00 insns per cycle [71.41%]
34,351,189,050 instructions:u # 3.99 insns per cycle [71.44%]
32,765 cache-references [71.46%]
3,266 cache-misses # 9.968 % of all cache refs [71.47%]
8,600,461,054 cycles # 0.000 GHz [71.46%]
34,378,806,261 instructions # 4.00 insns per cycle [71.41%]
17,192,017,836 branches [71.37%]
143 faults
2 migrations
281 context-switches
2.740606064 seconds time elapsed
观察结果
- 由于导致重新调度的控制路径不同,内核空间指令的数量也不同。除了最后一个之外,没有涉及任何系统调用
sys_exit
。显然,集合 A 的上下文切换次数更高。 - 用户空间指令()也有很小的差异
~10M
。这可能是由与上述相同的原因造成的?导致重新调度的指令被视为用户空间。还是中断上下文中的指令? - 组 A 的指令总数
0.06%
较高,但数量L3 cache references
是两倍。这是预期的吗?快速检查缓存配置得出相同的结果。缓存已正确启用(CR0: 0x80050033
,CD 为 0)且MTRR
配置相同。 - 可能最有趣的值是每个周期的指令。A 组每周期 1 个实例,B 组每周期 4 个实例。
最后的问题
是否有一个明显的原因可以解释这种性能差异?
为什么在硬件/软件配置相同的情况下,A 组中的机器以每周期 1 条指令的速度运行,而 B 组中的机器却以每周期 4 条指令的速度运行?
为什么重新启动机器似乎可以解决此问题?如简介中所述,如果我重新启动 A 组中的一台机器,它将开始按预期运行。
这里的原因要么太过琐碎以至于我没注意到,要么太过复杂以至于无法真正解释。我希望是前者,任何帮助/提示/建议都值得感激。
答案1
当然,如果有人能给出一个可以立即解决你的问题的答案,那就太好了。但我担心,没有明显的答案。但可能有一些尚未尝试过的解决问题的方向:
假设您的某些机器有时会出现这种行为,而其他机器则从不出现,那么可以推断出存在细微的硬件问题(偶尔出现,无法通过系统诊断检测到)。相反的假设是,这种情况可能发生在您的任何机器上。
- 步骤1:确保机器的所有部件都可以被跟踪。
- 第 2 步:挑选一些所谓的“好”机器,并与一些“坏”机器的硬盘一起运行,看看是否出现效果。
- 步骤 3:控制步骤。将“坏”机器与“好”机器的硬盘一起运行,看看是否会出现问题。
如果这种效果在“好”的机器上也能看到,那一定是安装(高清内容)有细微的差别,或者是硬盘有问题。
如果这种影响从未在“好”的机器上出现,那么“细微硬件问题”理论就得到了证实。
- 寻找那些“确实且显然不会导致这种情况发生 - 永远不会!”的差异。有一个故事讲的是通用汽车的工程师被派去调查,为什么通用汽车的车主在购买草莓冰淇淋时无法启动,而在商店购买香草冰淇淋时却无法启动……对于您来说,看看好机器和坏机器的放置位置。房间通风多一点还是少一点?靠近一些窗户和直射阳光?靠近/远离一些电气设备(气候控制,...)?建筑物的不同供电网络?更多的东西连接到一些电源控制路径/USV?...乍一看,我在这里提出的建议似乎不合理,但是嘿 - 您的问题相当零星,对吧?(正常运行时间为 50 天,您的机器在此期间“转动”...)。
将好的机器放到坏的机器的物理位置,看看会发生什么。
- 作为一名嵌入式软件工程师,我工作中遇到过一些比较痛苦的日子,因为有人在我的办公桌上更换“相同的设备”……我花了半天时间——半个星期的时间试图找出为什么我的东西不能像我晚上离开前那样工作……有时,即使是对某个组件(或闪现到其中的软件/配置版本)进行最微小的修改也会产生一些可观察到的影响。在我遇到的一些类似情况下,甚至制造商也没有意识到这些“不重要”的变化——有时只是在某些 PCB 布局或电容器供应商更改为第二个来源时……
步骤 1 应该有助于发现这些细微的差异,确定哪些机器可以工作,哪些不能。步骤 3 是寻找原因。
- 尝试评估“MTBF”并分析其模式。正如您可以清楚地看到的那样,当一台机器开始减速时,您可以测量机器减速所需的平均时间。然后,如果不同的机器有不同的故障时间,时间是否集中在一个值附近,或者根本没有模式(发生时完全随机),那么就可以洞察到......