Linux系统基准测试
1. 简介
在本教程中,我们将介绍用于图形和命令行环境的专用 Linux 基准测试工具。
此外,我们将看到不涉及任何特定 Linux 发行版的示例。因此,我们不会介绍如何安装各种工具,因为安装过程通常取决于发行版。
2. 对标和强调的有用性
基准可以帮助评估我们机器在特定任务中的性能。我们还可以使用基准来比较两台机器或将我们的计算机与分数数据库 进行比较。
我们可以使用已经在网络上发布的排名来选择要购买的硬件,如openbenchmarking.org 提供的这个例子:
有时我们需要进行基准测试以优化系统性能并消除由硬件或软件引起的瓶颈,例如有问题的更新、回归和错误的驱动程序。基准测试还可以方便地评估虚拟专用服务器 (VPS) 的特性。
强调类似于但不等同于基准测试,因为我们不需要它来评估性能。相反,它可以帮助我们发现重负载下的错误并评估我们的系统扩展性如何。一般来说,我们可以通过显着增加其执行时间将任何基准变成压力工具。
3. 测量硬盘性能时的陷阱
首先,让我们避免使用dd 来测试写入零或随机数据的速度。dd很受欢迎,因为它预装在几乎所有 Linux 发行版上,但它会给我们带来不切实际的结果。事实上,一些文件系统和磁盘以特定方式处理写入零和其他可压缩数据,这将导致基准测试结果过高。另一方面,如果我们使用随机生成器,我们将测量那个而不是磁盘。
我们还要记住,基准测试结果可能会受到以下因素的影响:
- 文件系统类型
- 磁盘加密
- 缓存及其属性
- 当前和以前的工作负载
- 碎片化
- 块大小
- 读/写比率
- 队列深度
- 数据类型,例如,顺序或随机
- 测试硬件,如CPU、接口、芯片组
- 软件,例如操作系统和驱动程序
另一个问题是弄清楚我们想要测量什么。我们可以将磁盘推送到工作站或服务器中永远不会发生的不切实际的边缘情况。尽管如此,不太可能的情况很少能提供有用的性能数据。最好的基准标准是我们的实际工作量。
我们还应该注意不要让我们的磁盘受到压力过大的基准测试。所有磁盘都有一些写入磨损,因此在相同位置重复写入数千次的运行测试会缩短它们的寿命。
此外,某些设备可能具有智能磨损均衡算法,该算法使用内部缓存来替换快速重写的数据,而无需接触磁盘。当然,这种内部缓存会让我们看到比真实结果更乐观的结果。
4. 硬盘基准测试工具
除了使用的工具之外,磁盘基准测试感兴趣的测量方法是:
- IOPS → 每秒 I/O 操作
- 吞吐量或带宽→每秒传输的数据量
- 延迟→ 执行 I/O 操作所需的时间
假设可能出现的问题,让我们尝试一些工具。
4.1. hdparm
我们已经讨论了hdparm 以区分 SSD 和 HDD 。hdparm是一个用于收集和操作 SATA/PATA/SAS 和旧 IDE 存储设备的低级参数的工具。它还包含一个基准模式,我们可以使用*-t*标志调用,即使在已安装分区的磁盘上:
# hdparm -t /dev/sda
/dev/sda:
Timing buffered disk reads: 1512 MB in 3.00 seconds = 503.87 MB/sec
该测试表明磁盘可以多快地支持顺序数据读取,而无需任何文件系统开销且无需事先缓存 ,因为hdparm会自动刷新它。
根据手册页,我们最好在没有其他活动进程且至少有几兆可用内存的系统上重复此基准测试两到三遍。
让我们尝试通过重复测量 3 次来比较两个磁盘。在本例中,sda是 SSD,sdb是 HDD:
# for i in {1..3}; do hdparm -t /dev/sda; hdparm -t /dev/sdb; done
所以我们看到sda在读取上比sdb快 3.6 倍:
/dev/sda:
Timing buffered disk reads: 1508 MB in 3.00 seconds = 502.18 MB/sec
/dev/sdb:
Timing buffered disk reads: 420 MB in 3.00 seconds = 140.00 MB/sec
/dev/sda:
Timing buffered disk reads: 1510 MB in 3.00 seconds = 502.52 MB/sec
/dev/sdb:
Timing buffered disk reads: 426 MB in 3.01 seconds = 141.39 MB/sec
/dev/sda:
Timing buffered disk reads: 1512 MB in 3.00 seconds = 503.66 MB/sec
/dev/sdb:
Timing buffered disk reads: 424 MB in 3.01 seconds = 140.85 MB/sec
将sda (502MB/s)的值与openbenchmarking.org的性能指标 进行比较,我们注意到性能非常出色,属于最高值。
4.2. fio
fio 代表 Flexible I/O Tester,指的是用于测量 I/O 性能的工具。**使用fio,我们可以设置我们的工作量以获得我们想要的测量类型**。
–filename标志允许我们测试块设备,例如*/dev/sda*,或者只是一个文件。但是,写入块设备会覆盖它,使其包含的数据不可用。另一方面,我们可以安全地使用设备名称和*–readonly*选项。
让我们从一个简单的例子开始,类似于hdparm的例子:测量*/dev/sda和/dev/sdb的连续读取速度三秒(–runtime=3*)。我们用–name命名测试,–rw决定顺序(–rw=read)或随机 I/O 访问:
# fio --filename=/dev/sda --readonly --rw=read --name=TEST --runtime=3
输出非常冗长,但我们对这一行感兴趣:
read: IOPS=128k, BW=498MiB/s (523MB/s)(1496MiB/3001msec)
带宽*(523MB/s )* 与hdparm ( 502MB/s ) 的带宽非常相似。我们注意到*/dev/sdb的带宽是 147MB/s,而hdparm 的*带宽是 141MB /s。
让我们看看*–rw*的所有选项:
- read→ 顺序读取
- write→ 顺序写入
- randread → 随机读取
- randwrite → 随机写入
- rw , readwrite → 混合顺序读写
- randrw → 混合随机读写
fio的选项 及其可能的组合有很多并且可能令人困惑,如手册页所示。这就是为什么Oracle 发布了用于块卷性能测试的示例 FIO 命令 ,涵盖了最常见的场景。
一旦找到我们感兴趣的工作负载,**我们就可以使用作业文件进行测试,**而无需命令行选项。因此,我们可以将前面的示例保存在test.fio中:
[global]
runtime=3
name=TEST
rw=read
[job1]
filename=/dev/sda
我们可以再次执行测试,可选择添加*–readonly*以提高安全性:
# fio --readonly test.fio
让我们在更人性化的环境中检查实际结果。
4.3. gfio
gfio 是一个基于 GTK+ 的fio的 GUI 前端。在某些情况下,例如访问*/dev/sda*,它可能需要 root 权限才能正常工作,与fio相同。它为我们提供了详细的报告和图表,以及一个自动生成或修改作业文件的编辑器。
以下屏幕截图来自上面的test.fio,但来自虚拟机:
与主机相比,安装在*/dev/sda*
上的此虚拟机的性能下降了 55% 。例如,带宽从 523MB/s 下降到 237MB/s,总读取 IO 操作从 1496MiB/3001msec 下降到 677MiB/3001msec,IOPS 从 128k/s 下降到 57.8k/s。 对于fio和gfio提供的所有其他信息,我们可以参考这个综合文档 。
4.4. sysbench
sysbench 是用于评估参数的模块化、跨平台和多线程基准测试工具,对于在高负载下运行数据库非常重要。幸运的是, sysbench直接与操作系统交互,因此它独立于任何特定的数据库。
首先,我们必须创建一组测试文件作为 I/O 目标。为此,我们使用 sysbench 的 fileio数来进行 I/O 测试。–file-total-size标志指示要在本地创建的测试文件的总大小。我们在实际运行之前执行准备:
$ mkdir tempBenchmarkFiles
$ cd tempBenchmarkFiles
$ sysbench fileio --file-total-size=50G prepare
在此示例中,该工具将创建 128 个文件,每个文件大约 400MB,用零填充。然后,我们就可以实际运行磁盘基准测试了。
例如,让我们执行一个随机读/写工作负载:
$ sysbench --file-total-size=50G --file-test-mode=rndrw --file-extra-flags=direct fileio run
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1
Initializing random number generator from current time
Extra file open flags: directio
128 files, 400MiB each
50GiB total file size
Block size 16KiB
Number of IO requests: 0
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Initializing worker threads...
Threads started!
File operations:
reads/s: 1310.23
writes/s: 873.52
fsyncs/s: 2796.86
Throughput:
read, MiB/s: 20.47
written, MiB/s: 13.65
General statistics:
total time: 10.0194s
total number of events: 49791
Latency (ms):
min: 0.06
avg: 0.20
max: 22.64
95th percentile: 0.45
sum: 9960.44
Threads fairness:
events (avg/stddev): 49791.0000/0.00
execution time (avg/stddev): 9.9604/0.00
–file-extra-flags=direct选项告诉sysbench使用直接 I/O,这将绕过页面缓存。这种选择可确保测试与磁盘交互,而不是与主内存交互。我们还可以使用*–time*标志设置以秒为单位的持续时间。
–file-test-mode接受以下工作负载:
- seqwr → 顺序写入
- seqrewr → 顺序重写
- seqrd → 顺序读取
- rndrd → 随机读取
- rndwr → 随机写入
- rndrw → 组合随机读/写
最后,让我们删除临时文件:
$ sysbench fileio cleanup
手册页有点简洁。我们还可以深入研究综合手册sysbench-manual.pdf 。
5. CPU 基准测试
CPU 基准测试的核心方面是选择哪些计算来测量. 理论上,我们不需要任何特定的软件。
例如,我们可以决定在不同的机器上编译相同的软件,或者散列数百个重文件,然后比较时间。当然,边界条件必须相同:操作系统、文件、用于编译或散列的选项等等。此外,我们可以创建一个小型 Bash 脚本,将某些计算重复一百万次。但是,只有当我们对特定任务感兴趣时,这种方法才会有效。
对于更一般的 CPU 测试,Geekbench 似乎相当完整。它是一个命令行工具,可针对以下单核和多核测试来测试 CPU:
- AES-XTS
- 文本压缩
- 图像压缩
- 导航
- HTML5
- SQLite
- PDF 渲染
- 文本渲染
- 铛
- 相机
- N体物理
- 刚体物理
- 高斯模糊
- 人脸检测
- 地平线检测
- 图像修复
- HDR
- 光线追踪
- 运动结构
- 语音识别
- 机器学习
它是具有免费版本的专有软件。在基准测试结束时,Geekbench 会在线上传结果并给我们一个类似这样的链接 来查看它们。
然后我们可以将我们的 CPU 与Geekbench 基准数据库 进行比较。同样,我们还可以与来自openbenchmarking.org的性能指标 进行比较,注意到屏幕截图中显示的结果非常低。
6. GPU 功能
有人可能会认为评估显卡性能几乎专门用于游戏。它没有。
例如,让我们考虑一下增强现实 (AR) 或沉浸式虚拟现实 (VR)。除了选择合适的 VR 头戴设备或最有效的 AR 软件之外,要打造完美的 VR 体验还需要更多。确保我们获得真正逼真的 VR 体验的重要工具之一是我们的 GPU。
我们还可以考虑机器学习 (ML),它是人工智能 (AI) 的一个子集。ML 是计算机系统学习根据观察和数据做出决策和预测的能力。GPU 是一种具有增强数学计算能力的专用处理单元,非常适合 ML。
另一个有趣的例子是加密货币的开采,比如比特币或以太坊。挖矿是创建交易块并将其添加到区块链的过程。我们需要专门的硬件来解决复杂的数学难题,例如出色的显卡。例如,开采以太币的 VRAM(视频 RAM)要求超过 4GB。但这只是最低要求。
从这些观察中可以清楚地看出,如果我们计划运行特定任务,GPU 基准测试是不够的。在此处建议的示例中,我们必须彻底调查所需的硬件。
7. GPU 基准测试
通常,GPU 基准测试涉及动态创建或多或少复杂的运动图像以及每秒帧数 (fps) 的测量。
一般来说,fps值越高越好。高值意味着视频卡可以毫无困难地渲染 3D 场景。低值意味着图形工作的复杂性对于显卡来说太高了。对于人眼来说,60fps 的电影是可取的。
让我们记住,低基准分数并不一定表示 GPU 有故障。旧驱动程序、开源驱动程序而不是专有驱动程序(反之亦然)、过热或电源问题都可能导致低分。
7.1. glmark2
*glmark2 * 有一套场景来衡量OpenGL (ES) 2.0 性能的许多方面。我们可以通过一组选项来配置每个场景的渲染方式。完成测试并提供分数需要几分钟。这是其中一个场景:
在我们的一台虚拟机中,这项综合测试提供了以下日志记录和最终分数:
$ glmark2
=======================================================
glmark2 2014.03+git20150611.fa71af2d
=======================================================
OpenGL Information
GL_VENDOR: VMware, Inc.
GL_RENDERER: SVGA3D; build: RELEASE; LLVM;
GL_VERSION: 2.1 Mesa 20.0.8
=======================================================
[build] use-vbo=false: FPS: 615 FrameTime: 1.626 ms
[build] use-vbo=true: FPS: 2364 FrameTime: 0.423 ms
[texture] texture-filter=nearest: FPS: 1567 FrameTime: 0.638 ms
[texture] texture-filter=linear: FPS: 1546 FrameTime: 0.647 ms
[texture] texture-filter=mipmap: FPS: 1525 FrameTime: 0.656 ms
[shading] shading=gouraud: FPS: 1563 FrameTime: 0.640 ms
[shading] shading=blinn-phong-inf: FPS: 1491 FrameTime: 0.671 ms
[shading] shading=phong: FPS: 1338 FrameTime: 0.747 ms
[shading] shading=cel: FPS: 1334 FrameTime: 0.750 ms
[bump] bump-render=high-poly: FPS: 1443 FrameTime: 0.693 ms
[bump] bump-render=normals: FPS: 1395 FrameTime: 0.717 ms
[bump] bump-render=height: FPS: 1279 FrameTime: 0.782 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 1420 FrameTime: 0.704 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 1427 FrameTime: 0.701 ms
[pulsar] light=false:quads=5:texture=false: FPS: 610 FrameTime: 1.639 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 247 FrameTime: 4.049 ms
[desktop] effect=shadow:windows=4: FPS: 220 FrameTime: 4.545 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 184 FrameTime: 5.435 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 233 FrameTime: 4.292 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 235 FrameTime: 4.255 ms
[ideas] speed=duration: FPS: 668 FrameTime: 1.497 ms
[jellyfish] <default>: FPS: 1734 FrameTime: 0.577 ms
Error: SceneTerrain requires Vertex Texture Fetch support, but GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS is 0
[terrain] <default>: Unsupported
[shadow] <default>: FPS: 1023 FrameTime: 0.978 ms
[refract] <default>: FPS: 868 FrameTime: 1.152 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 1715 FrameTime: 0.583 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 1463 FrameTime: 0.684 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 1425 FrameTime: 0.702 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 1432 FrameTime: 0.698 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 1405 FrameTime: 0.712 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 1357 FrameTime: 0.737 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 1269 FrameTime: 0.788 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 1311 FrameTime: 0.763 ms
=======================================================
glmark2 Score: 1178
=======================================================
根据openbenchmarking.org上报告的 800×600 像素的性能指标 ,该分数太低,无法获得不错的性能。相比之下,中位得分为 3172,中位得分为 7765。
7.2. geeks3d 的 GpuTest
geeks3d 的 GpuTest 是一个跨平台的免费 OpenGL 基准测试。它包含几个 GPU 基准(furmark、gimark、pixmark 等)和详尽的README.txt。
以下屏幕截图是 pixmark 基准测试的示例。请注意,标题栏实时显示fps 。**当测试结束时,它也会给我们一个分数,我们可以将它与这个更新的分数数据库 **进行比较。
将我们的结果与介于 85324 和 180278 之间的前 20 名得分 进行比较,我们了解到我们的 GPU 有严重的局限性。
8. RAM 基准测试
我们可以认为相同类型的记忆棒在两台不同的机器上表现相似,但这种情况很少见。RAM 性能更多地取决于 CPU 和主板,而不是内存类型和速度。另一方面,RAM 的数量是一般系统性能的决定因素。
考虑到这一点,让我们使用sysbench对 RAM 进行基准测试。
8.1. sysbench
默认情况下,除非我们使用*–memory-oper=read* ,否则该工具会执行写入测试:
$ sysbench memory --memory-access-mode=rnd run
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1
Initializing random number generator from current time
Running memory speed test with the following options:
block size: 1KiB
total size: 102400MiB
operation: write
scope: global
Initializing worker threads...
Threads started!
Total operations: 20126299 (2012308.75 per second)
19654.59 MiB transferred (1965.15 MiB/sec)
General statistics:
total time: 10.0001s
total number of events: 20126299
Latency (ms):
min: 0.00
avg: 0.00
max: 0.04
95th percentile: 0.00
sum: 8260.00
Threads fairness:
events (avg/stddev): 20126299.0000/0.00
execution time (avg/stddev): 8.2600/0.00
–memory-access-mode的可能值为seq(默认为顺序访问)和rnd(随机访问)。要查看所有选项,我们可以使用 sysbench memory help。
8.2. 比较 RAM 基准
将之前获得的值(1965.15 MiB/秒)与openbenchmarking.org的性能指标 进行比较,结果似乎低于最小值。然而,来自openbenchmarking.org的值可能指的是顺序只写测试,我们可以使用sysbench memory run来运行该测试。在这种情况下,我们得到 5847.83 MiB/秒,非常接近中值。
此外,我们还可以评估虚拟机中的 RAM 性能是否低于其主机的 RAM 性能:
$ sysbench memory --memory-access-mode=rnd run
sysbench 1.0.11 (using system LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 1
Initializing random number generator from current time
Running memory speed test with the following options:
block size: 1KiB
total size: 102400MiB
operation: write
scope: global
Initializing worker threads...
Threads started!
Total operations: 17710992 (1770824.00 per second)
17295.89 MiB transferred (1729.32 MiB/sec)
General statistics:
total time: 10.0001s
total number of events: 17710992
Latency (ms):
min: 0.00
avg: 0.00
max: 1.02
95th percentile: 0.00
sum: 7772.77
Threads fairness:
events (avg/stddev): 17710992.0000/0.00
execution time (avg/stddev): 7.7728/0.00
在这种情况下,我们可以看到相当微不足道的退化(10%)。