是什么导致软件在更好的硬件上运行速度变慢?

时间:2018-07-31 13:42:23

标签: java osgi performance-testing multicast latency

我有一个运行在RHEL 7.4上的Java OSGi(Apache Felix)应用程序,它以〜975个数据包/秒(长度为1038个八位字节)的速度读取多播UDP。然后,它将数据转换为XML,模拟跨边界设备,然后将其转换回UDP多播数据包。涉及多个线程,其编写方式是:如果模拟边界设备花一点时间来处理一个有效载荷,它将对其进行缓冲并在下一次发送更大的有效载荷。

在通过这种集成测试方案查看数据包延迟时,两台不同的台式机比我们预期部署的相当高端的服务器要快得多。

  • 服务器延迟5秒。硬件:双Xeon E5-2667v4 @ 3.2GHz,128G RAM,16个物理,21个逻辑内核,RAID 1 SAS SSD。
  • 桌面A <1秒。硬件至强E5-1620v4 @ 3.5Ghz,64G RAM,4个物理,8个逻辑内核,500G SSD
  • 桌面B <1秒。 HW i7-3770 @ 3.4Ghz,16G RAM,4个物理,8个逻辑内核,1TB 7200RPM驱动器。

我只提到硬盘驱动器的完整性,因为此应用程序未写入磁盘。在纸上,服务器的性能至少应与两个台式机一样快。

我消除的东西

  • 网卡。我已经对物理NIC和虚拟设备进行了测试,以防万一NIC之间存在显着差异。
  • 逻辑核心数。我尝试禁用16个和24个服务器逻辑核心,以排除变量。
  • Java版本。这三种方法都已经在OpenJDK和Oracle Java(具有相同版本(Java 1.8.0)的Java上进行了尝试,得出相同的结果。
  • Java标志是相同的,并且都与felix(安装目录,配置属性和要执行的jar)有关。
  • SELinux。我已经在所有三种模式(禁用,强制,允许)中进行了尝试。我没想到这里会有所不同,但现在我正在抓紧一切。
  • 内核版本。我已经针对3.10.04.13.04.15.0进行了测试,结果相似。

ark.intel.com processor comparison

这里有两个示例图来说明问题。此测试在4分钟10秒内向多播地址A发送260,960个UDP数据包,并在通过应用程序对其进行处理后,将数据包发送到多播地址B。tcpdump记录了两者的时间戳,减法会产生延迟。这三个应用程序(发件人,应用程序,tcpdump都在同一台计算机上。)

首先针对虚拟接口的服务器硬件 server

i7桌面硬件针对虚拟接口 i7-desktop

请注意Y轴比例差异。服务器为0-4秒,i7桌面为0-1秒。似乎难以阅读的X轴是数据包编号。

下次尝试

我正在运行该应用程序的本地集成版本。然后,我消除了应用程序开始完成的几乎100%的工作,并发现服务器硬件上的延迟越来越大。然后,我尝试使用-Xmx100G -Xms100G从本质上阻止垃圾收集器运行EVER,并看到以下结果(<1秒一致的延迟)。

Huge Memory

是谁带我去Java 8's Available Garbage Collectors的。

服务器硬件上的默认垃圾收集器选择为“新:ParallelScavenge”,旧:“ ParallelOld”。这是没有XML转换的结果延迟图,这是我可以使其重现问题的简单测试。

Default GC

明确选择“垃圾第一垃圾收集器” -XX:+UseG1GC,选择“新建”:“ G1New”,“旧”:“ G1Old”,其产生的延迟图也不好:

G1 GC

明确选择并发标记扫描垃圾收集器-XX:+UseConcMarkSweepGC,选择新的:ParNew,旧的:ConcurrentMarkSweep,其延迟图看起来非常好:

CMS GC

问题似乎已解决。将所有组件添加回原位后,我仍然会遇到无法接受的延迟。我仍在运行测试,以查看是否可以找出问题所在。

跟踪结果

尝试strace -c -o /path/to/file -f产生了以下顶级系统调用

首先是i7的台式机strace报告(在前10个项目中被截断)

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 93.71 1418.604132         959   1479659    134352 futex
  1.74   26.294223      730395        36           poll
  1.74   26.288786         314     83645         4 read
  1.41   21.373672          73    293618           epoll_pwait
  1.19   17.952475         120    149854         2 recvfrom
  0.10    1.448453           2    909731           getrusage
  0.06    0.896903           3    281407           sendto
  0.03    0.394695           2    198041           write
  0.01    0.182809          10     18246           mmap
  0.01    0.120735           6     20582           sched_yield

现在要获取服务器的strace报告:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 97.46 2119.311196        2642    802183    131276 futex
  1.28   27.734136     6933534         4           poll
  0.59   12.840448          49    263597           epoll_wait
  0.41    8.885742         113     78387         2 recvfrom
  0.07    1.575401           6    263671           sendto
  0.07    1.515999           6    262256           epoll_ctl
  0.04    0.902788          54     16800           sched_yield
  0.03    0.743231          10     75455           write
  0.02    0.490052           6     84509         7 read
  0.01    0.170152           4     42732           lseek

我不清楚我应该从中得出什么结论。在futexpoll系统调用中,桌面速度要快很多倍。我仍然不明白为什么该应用程序对更快的硬件如此潜伏。

分析

我已经在这两种硬件上对软件进行了概要分析,它们显示出热点的相似位置,似乎可以排除这一点。

1 个答案:

答案 0 :(得分:1)

我确认我正在将performance CPU调速器与RedHat:CPUfreq Coverners

一起使用

我遇到了关于BIOS设置Virtual Machine Application runs slower than expected on EXSi有问题的VMWare ESXi报告

哪个直接指向我的答案。该Dell R630的默认设置为“每瓦性能(DAPC)”(DAPC:Dell Active Power Controller)。切换到“性能”可以完全解决此问题。该机器在控制台上感觉更加敏捷,并且延迟远低于台式机所能达到的延迟,这是我预期的CPU差异。

在启动时更改Dell R630(可能还有其他)上的BIOS的步骤:

  1. F2进入系统设置程序
  2. 选择“系统BIOS”
  3. 选择“系统配置文件设置”
  4. 确保将第一个条目设置为“性能”,默认值为“每瓦性能”
  5. 选择“返回”
  6. 选择“完成”
  7. 选择“是”以保存系统重置更改
  8. 选择“确定”以成功保存设置

这是结果延迟图,它们使用相同的1秒刻度。

服务器上的默认GC: DefaultGC

服务器上的并发标记扫描GC: CMSGC

服务器上的第一代GC: G1GC

G1GC和CMSGC之间的差异不大,但显然都比默认延迟(预期的)要好。

逻辑核心时钟速度图

很难看到符号,但是这两张图上有32个不同的点。总体而言,您可以快速分辨出哪个是性能,哪个是每瓦dapc性能。

每瓦性能(DAPC): PerformancePerWattDAPC

性能 Performance

一起绘制。红色项目符号的性能,蓝色空心圆圈中的每瓦性能 Together

这是在300秒的数据流中捕获的,并相应设置了BIOS。这是我捕获数据的方式,以防万一有人想知道:

for i in `seq 300`; do
  paste /sys/devices/system/cpu/cpu[0-9]*/cpufreq/cpuinfo_cur_freq
  sleep 1
done > performance.log