一、CPU 基准性能测试

1.1 关于CPU频率

CPU 最核心的指标是主频,也就是 CPU 内核工作的主时钟频率。基频(Base Frequency)是指在普通状态,BIOS 关闭 Turbo 的时候,CPU 的最高频率不会超过的某个值,通常记为 P1。睿频(Turbo Frequency)指的是基频(P1)以上的频率,有两个关键的睿频。一个是全核睿频(P0n),指的是一个 CPU 上所有核心都超频时,可以达到的频率。一个是单核最大睿频(P0),指的是单个核心超频时,可以达到的最大频率。 三者的关系如下:

image-20220523170324198

通常,我们只说基频和全核睿频,一般不提单核睿频,因为要达到单核睿频通常需要 关闭 CPU 的一部分核心才能让剩余的核心达到单核睿频的频率。

1.2 查看CPU频率

  • 查看基频

    1# yum install kernel-tools -y
    2# turbostat
    

    image-20220523170416939

    这里基频是 2.5GHZ

  • 查看实际运行频率。

    1# wget http://www.bitmover.com/lmbench/lmbench3.tar.gz
    2# tar xzvf lmbench3.tar.gz
    3# yum -y install gcc make  
    4# CentOS 8 需要额外安装“libtirpc-devel” 否则报:fatal error: rpc/rpc.h: No such file or directory
    5# cd lmbench3
    6# make
    7# cd bin/x86_64-linux-gnu/
    8# ./mhz
    

    image-20220523170521263

    实际频率运行在 3.2GHZ 左右,是物理 cpu 的全核睿频频率。 注意:使用不同的服务器,主频可能不一样,这里的结果仅为示例。

1.3 SuperPI CPU性能测试

1.3.1 测试说明

SuperPI 是利用 CPU 的浮点运算能力来计算出π(圆周率),可以用做测试系统稳定性和测试 CPU 计算完后特定位数圆周率所需的时间。

  • 单核测试命令:

    1# time echo "scale=5000; 4*a(1)" | bc -l -q &> result.txt
    

    说明:计算原理简单介绍一下,由于 tan(PI/4)=1,所以有 PI=4*atan(1)。bc 命令是任意精度计算器语言,在 linux 下当做科学计算器使用。-l 指定采用标准数学库,-q 指定 quiet 模式,不打印欢迎语句。最后用 time 命令输出计算的时间,可以用时间的长短来衡量 CPU 核心的计算能力,比如同样计算到 PI 的小数点后 5000 位,计算时间越短,说明 CPU 核心的计算能力越强。

  • 多核心测试脚本:

    1# cat superpi_multicore.sh
    2
    3#!/bin/bash
    4cpu_seqs=`cat /proc/cpuinfo | grep proce | sed -e "s/.* //g" | tr -s '\n' ' '`
    5for cpu_seq in $cpu_seqs;do
    6	time echo "scale=5000; 4*a(1)" | taskset -c $cpu_seq bc -l -q &> result.txt &
    7done
    

    **说明:**以上脚本先获取云主机有多少个核心,然后根据这个核心数提交对应个数的 superpi 任务,让每个核心都跑一个 superpi 任务。

  • 测试步骤:

    1)单核心测试。

    1# time echo "scale=5000; 4*a(1)" | bc -l -q &> result.txt
    

    测试结果:

    image-20220523221308046

    **结果说明:**数值越小,表明时间越短,说明单核心计算能力越强。

    2)多核心测试

    1# cat superpi_multicore.sh
    2#!/bin/bash
    3cpu_seqs=`cat /proc/cpuinfo | grep proce | sed -e "s/.* //g" | tr -s '\n' ' '`
    4for cpu_seq in $cpu_seqs;do
    5	time echo "scale=5000; 4*a(1)" | taskset -c $cpu_seq bc -l -q &> result.txt &
    6done
    7
    8# sh superpi_multicore.sh
    

    测试结果:

    image-20220523221029622

    测试结果说明:

    1. 在服务器上,通常CPU的核心都是 vCPU,也就是说底层物理cpu开启了超线程后 一个物理核心可 以 虚 拟 出 两 个 vCPU 的 核 心 ,也称为两个HT(HyperThreading)。
    2. 对于企业级用户来说,通常为了 CPU 性能运行稳定,一般会限定同一个物理核心的虚拟出的两个 vCPU 绑定在一个云服务器实例上,也称之为PIN 住。
    3. 对于 CPU PIN 住的实例来说,对于单个物理核心上的两个 vCPU 来说,单 vCPU运行 superPI,另一个vCPU 闲置的时候,跑 superPI 的 vcpu 是可以用到所有物理核心的计算能力的。因此对于CPU PIN住的云服务器来说,当两个vCPU同时跑 superPI 时(多进程),用时会比只有单 vCPU 跑的时候耗时会更多。如上面的测试结果就是这种情况,多进程用时比单进程用时长。
    4. 如果 CPU 没有 PIN 住,跑出来的时间可能是一样的。表面上看 CPU 没有pin住,似乎对客户来说有利,实际上云上的环境通常是多租户的,在 CPU 没有 pin 住的时候,用户的应用更容易受到其他用户的应用的影响,从而无法获取稳定的性能输出。

1.4 Unixbench 测试

1.4.1 测试说明:

unixbench 是一个用于测试 unix 系统性能的工具,也是一个比较通用的 benchmark,此测试的目的是对类 Unix 系统提供一个基本的性能指示,很多测试用于系统性能的不同方面,这些测试的结果是一个指数值(index value,如 520),这个值是测试系统的测试结果与一个基线系统测试结果比较得到的指数值,这样比原始值更容易得到参考价值,测试集合里面所有的测试得到的指数值结合起来得到整个系统的指数值。

1.4.2 测试步骤:

  • 下载测试工具包。

    1# yum install perl-Time-HiRes
    2# wget https://github.com/aliyun/byte-unixbench/releases/download/v5.1.4/UnixBench-5.1.4.tar.gz
    3# tar xzvf UnixBench-5.1.4.tar.gz
    4# cd UnixBench
    
  • 单核测试

    1# ./Run -c 1
    

    **注意:**执行期间不要执行其他命令,执行完毕结果会打印到屏幕上.sh: 3dinfo: command not found 是用于CPU的3D 性能测试的,不用理会。

    image-20220523221647999

    image-20220523224550606

    image-20220523224615575

    **结果说明:**Index 数值越高越好。

  • 多核测试

    1# 运行 ./Run -c ${core}
    2# (core 为 cpu 线程数,可通过命令"cat /proc/cpuinfo | grep process | wc -l" 获取)
    3# cat /proc/cpuinfo | grep process | wc -l
    44
    5# ./Run -c 4
    

    image-20220523171810569

    **结果说明:**Index 数值越高越好。

二、内存基准性能测试

2.1 查看内存容量

1[root@storage01 UnixBench]# free -m
2              total        used        free      shared  buff/cache   available
3Mem:           1950        1117         155          21         677         655
4Swap:          2079          76        2003

2.2 Stream 内存带宽测试

  • 2.3.1 Stream 使用说明:
1stream 是业内公认的用于内存性能评估的基准测试软件,其包括 Copy(复制)、Scale(乘法)、Add(加法)以及 Triad(三者复合)四种不同操作情况下的内存带宽表现。
2复制(Copy) a(i) = b(i)
3尺度变换(Scale) a(i) = q*b(i)
4矢量求和(Add) a(i) = b(i) + c(i)
5复合矢量求和(Triad) a(i) = b(i) + q*c(i)

Stream 官网地址 https://www.cs.virginia.edu/stream/ Stream 使用说明 https://www.cs.virginia.edu/stream/ref.html

参数设置说明

  1. Copy 是复制操作,从一个内存单元中读取一个数,并复制到另一个内存单元。

  2. Scale 是乘法操作,从一个内存单元中读取一个数,与常数相乘后,将结果写入另一个内存单元。Add 是加法操作,从两个内存单元中分别读取两个数,相加后,将得到的结果写入另一个内存单元中。

  3. Triad 是前面三种的结合,先从内存中读取一个数,与常数相乘后,得到一个乘积,然后从另一个内存单元中读取一个数与之前的乘积相加,得到的结果再写入内存。

  4. 程序有三个重要参数需要设置,STREA_ARRAY_SIZE,NTIMES 以及 OFFSET。这三个参数的设置可以参考源码中的说明。

    1STREAM_ARRAY_SIZE,默认是 10000000。表示测试数据集的大小,该大小应
    2该遵循以下两条规则。
    31. 数据集大小应不小于 L3 cache 大小的 4 倍。
    4	例如:配置两个 E5 CPU 的服务器,每个 cpu 有 20MB 的 L3 Cache,两个 cpu 共计 40MB。
    5		40MB*4=160MB,每个数据大小是 8Byte,因此数据集大小应该大于160MB/8B=20Million。
    62. 数据集大小应能确保程序输出时间大于 20 个时钟周期。
    73. 本例中,我们使用尽量大的 STREAM_ARRAY_SIZE 来进行测试。
    
    1NTIME。该参数为 kernel 执行的次数,程序将输出除第一次外其他结果中最好的
    2结果,所以 NTIME 的最小值是 2。该值默认为 10,通常不许要修改。
    
  • 2.3.2 下载 stream 源码文件,项目:https://github.com/intel/memory-bandwidth-benchmarks

    1# https://raw.githubusercontent.com/intel/memory-bandwidth-benchmarks/master/stream.c
    2# yum -y install gcc
    3# ls stream.c
    
  • 2.3.3 创建编译测试脚本

     1# cat stream_test.sh
     2
     3#!/bin/bash
     4# 获取可用 memory
     5available_memory_size=`free -m | grep Mem | awk '{print ($4)*1024*1024}'`
     6# 计算最大 array_size
     7array_size=$((available_memory_size/8/3))
     8# 编译 stream
     9gcc -O stream.c -fopenmp -DSTREAM_ARRAY_SIZE=$array_size -DNTIME=30 -mcmodel=medium -o stream.o
    10# 执行测试
    11./stream.o
    
  • 执行测试

    1# chmod +x stream_test.sh
    2#./stream_test.sh
    

    image-20220523224917881

    image-20220523173131338

    示例内存 16GB,这里使用了 13.6GB 来进行测试。 **结果说明:**Best Rate 数值越高越好。

2.3 MLC 内存延迟测试

  • MLC 使用说明: mlc 为 intel 的内存测试工具,可以有效方便的测试内存延时。

  • 下载

    1https://www.intel.com/content/www/us/en/developer/articles/tool/intelr-memory-latency-checker.html
    2# 需要手动下载,无法使用wget,有安全申明需要web确认。
    
  • 安装

    1# tar xzvf mlc_v3.9a.tgz
    2# yum install -y glibc
    
  • 测试步骤

    1# ./Linux/mlc --idle_latency -e -r -l128 -D8192
    

    image-20220523225436396

    image-20220523173426919

    重复运行 10 次,求平均值结果中小括号中的 ns 值即为结果。 结果说明:ns 数值越低越好。

    参数意义:

    1--idle_latency prints the idle memory latency of the platform
    2-e do not modify the h/w prefetcher states
    3-r random access reads for latency thread
    4-l stride length in bytes (default=64)
    5-D random access range for latency thread (default=4096)
    

    参考文档: https://software.intel.com/content/www/us/en/develop/articles/intelr-memory-latency-checker.html

三、 网络基准性能测试

3.1 网络测试方法说明

​ Netperf 是一种网络性能的测量工具,主要针对基于 TCP 或 UDP 的传输。Netperf 根据应用的不同,可以进行不同模式的网络性能测试,即批量数据传输(bulk data transfer)模式和请求/应答(request/reponse)模式。Netperf 测试结果所反映的是一个系统能够以多快的速度向另外一个系统发送数据,以及另外一个系统能够以多块的速度接收数据。访问 netperf 官网:www.netperf.org/

​ 具体测试时,选取相同配置的 2 台 Linux 云主机进行配置,云主机 A 上安装 netperf的 netserver 作为服务器端,云主机 B 上安装 netperf 作为客户端,在不运行应用情况下,云主机 B 压测云主机 A(不指定数据包大小),测试云主机 A 的网络 TCP 收带宽性能,结果为 Mb/s。

​ 网络压力持续时间为 5 分钟,取云主机 A 收到压力 50 秒后持续 200 秒的带宽平均值。

3.2 测试工具安装

  • 在两台 测试主机上上都安装 netperf

    创建测试脚本:

    1# vim install-netperf.sh
    2#!/bin/bash
    3wget -c https://codeload.github.com/HewlettPackard/netperf/tar.gz/netperf-2.7.0
    4tar -xzvf netperf-2.7.0
    5yum install gcc sysstat -y
    6cd netperf-netperf-2.7.0
    7./configure && make && make install
    8which netperf
    
  • 添加执行权限

    1# chmod +x install-netperf.sh
    
  • 执行并安装

    1# ./install-netperf.sh
    2
    3安装最后输出“/usr/local/bin/netperf”,表明安装成功。
    

    image-20220523230013605

3.3 创建测试脚本

  • 在 01号主机上上创建 server 端测试脚本

     1# cat streamserver.sh
     2
     3#!/bin/bash
     4connect_num=64
     5size=1
     6killall netserver
     7for j in `seq $connect_num`
     8do
     9	port=$[16000+j]
    10	netserver -p $port > netserverstream.log 2>&1 &
    11done
    

    **说明:**测试 64 个流。

  • 在 02号主机上创建 client 端带宽测试脚本

     1# vim streamclient.sh
     2
     3#!/bin/bash
     4server_ip=$1
     5connect_num=64
     6protocol=$2
     7size=1
     8killall netperf
     9for j in `seq $connect_num`
    10	do
    11		port=$[16000+j]
    12		netperf -H ${server_ip} -l 60 -t ${protocol} -p $port -- -m 1400 -D > netperfstream.log 2>&1 &
    13	done
    

    **说明:**测试 64 个流。

  • 在 02号主机上创建 client 端带宽测试脚本。

     1# vim udpclient.sh
     2
     3#!/bin/bash
     4server_ip=$1
     5connect_num=64
     6protocol=$2
     7size=1
     8killall netperf
     9for j in `seq $connect_num`
    10	do
    11		port=$[16000+j]
    12		netperf -H ${server_ip} -l 60 -t ${protocol} -p $port -l 300 -- -m 1 -D > netperfpps.log 2>&1 &
    13	done
    
  • 添加执行权限

    01号主机上:

    1# chmod +x streamserver.sh
    

    02号主机上

    1# chmod +x streamclient.sh
    2# chmod +x udpclient.sh
    

    通过 ip addr 查看主机的IP地址

    image-20220523230605440

    image-20220523230543174

    主机名称 内网IP 测试角色
    host01 192.168.111.201 Server
    host02 192.168.111.202 Client

3.4 测试网络多流TCP带宽

  • 在 server 上启动 streamserver.sh 忽略 no process found报错。

image-20220523230651312

  • 在 client 上启动 streamclient.sh忽略 no process found报错。

    1./streamclient.sh 192.168.111.201 TCP_STREAM
    

    image-20220523230835608

image-20220523180856994

**说明:**第一个参数指定 sever 的 eth0 内网地址,第二参数指定测试 TCP_STREAM。

  • sar 命令查看 rxkB/s
1# sar -n DEV 1 250

image-20220523180954685

通过 sar 命令查看的是 kB/s ,应该*8/1000 换算成 Mb/s。

结果说明:rxkB/s 数值越高越好。

3.5 测试网络多流 UDP 收 PPS

  • 在 server 上启动 streamserver.sh

image-20220523181059986

  • 在 client 上启动 streamclient.sh

image-20220523181113825

**说明:**第一个参数指定 sever 的 eth0 内网地址,第二参数指定测试 UDP_STREAM。

  • 在 server 端用 sar 命令查看 rxpck/s
1# sar -n DEV 1 250

image-20220523181241225

**结果说明:**rxpck/s 数值越高越好。

**注意:**对于高性能的主机,建议使用 2~3 个 client 对 server 进行压测,更能够客观反映其网络新能。

四、磁盘性能测试

对于磁盘来说,最关注的指标一般是顺序读写的带宽和随机读写的 IOPS,前者通常测试 IO 大小是 1M 的情况,后者一般是 4K。测试工具建议采用 FIO

4.1 下载安装测试工具

1# wget https://codeload.github.com/axboe/fio/tar.gz/fio-3.8
2# tar xzvf fio-3.8
3# cd fio-fio-3.8/
4# yum install libaio libaio-devel gcc-c++ -y
5# ./configure && make && make install
6# which fio
7/usr/local/bin/fio

4.2 带宽测试

本次测试/dev/vdb 这块磁盘,用-filename=/dev/vdb 来指定

  • 顺序写吞吐量(写带宽)
1# fio -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=1024k -size=10G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/vdb -name=Write_BW_Testing

image-20220523181706499

另一个terminal 查看:

1# iostat -m 5

image-20220523181748732

  • 顺序读吞吐量(读带宽)
1fio -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=1024k -size=10G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/vdb -name=Read_BW_Testing

image-20220523181823196

**结果说明:**bw 数值越高越好。

另一个terminal 查看:

1# iostat -m 5

image-20220523181924080

4.3 IOPS 测试

  • 随机写 IOPS:
1# fio -direct=1 -iodepth=128 -rw=randwrite -ioengine=libaio -bs=4k -size=10G -numjobs=1  -runtime=1000 -group_reporting -filename=/dev/vdb name=Rand_Write_Testing

image-20220523182044041

另一个terminal 查看:

1# iostat -m 5

image-20220523182117146

  • 随机读 IOPS:
1# fio -direct=1 -iodepth=128 -rw=randread -ioengine=libaio -bs=4k -size=10G -numjobs=1 -runtime=1000 -group_reporting -filename=/dev/vdb -name=Rand_Read_Testing

**结果说明:**IOPS 数值越高越好。

另一个terminal 查看:

1# iostat -m 5

image-20220523182300311

4.4 FIO 参数取值说明

以下为随机写 IOPS(randwrite)的命令为例,说明各种参数的含义。

属性 内容
-direct=1 表示测试时忽略 I/O 缓存,数据是否直写。
-iodepth=128 表示使用异步 I/O(AIO)时,同时发出 I/O 数的上限为 128。
-rw=randwrite 表示测试时的读写策略为随机写(random writes)。其它测试可以设置为 :randread(随机读 random reads)read(顺序读 sequential reads)write(顺序写 sequential writes)randrw(混合随机读写 mixed random reads and writes)
-ioengine=libaio 表示测试方式为 libaio(Linux AIO,异步 I/O)。应用程序使用 I/O通常有两种方式:同步同步的 I/O 一次只能发出一个 I/O 请求,等待内核完成才返回。这样对于单个线程 iodepth 总是小于 1,但是可以透过多个线程并发执行来解决。通常会用 16~32 根线程同时工作将iodepth 塞满。异步异步的 I/O 通常使用 libaio 这样的方式一次提交一批 I/O 请求,然后等待一批的完成,减少交互的次数,会更有效率。
-bs=4k 表示单次 I/O 的块文件大小为 4KiB。默认值也是 4KiB。测试 IOPS 时,建议将 bs 设置为一个较小的值,如 4k。测试吞吐量时,建议将 bs 设置为一个较大的值,如 1024k。
-size=1G 表示测试文件大小为 1GiB。
-numjobs=1 表示测试线程数为 1。
-runtime=1000 表示测试时间为 1000 秒。如果未配置,则持续将前述-size 指定大小的文件,以每次-bs 值为分块大小写完。
- group_reporting 表示测试结果里汇总每个进程的统计信息,而非以不同 job 汇总展示信息。
-filename=iotest 指定测试文件的名称,例如 iotest。
-name=Rand_WriteTesting 表示测试任务名称为 Rand_Write_Testing,可以随意设定。