4、测试工具链:sysbench、perf、stress-ng、自定义C压测工具的安装与基本使用

做嵌入式行情系统的性能测试,工具选对了,事半功倍。我这些年折腾下来,发现真正好用的工具其实就那么几个。今天咱们就把 sysbench、perf、stress-ng 和自定义 C 压测工具这四样东西,从安装到基本用法,一次性讲透。

核心观点:没有万能工具,只有最合适的组合。sysbench 适合宏观压测,perf 适合微观分析,stress-ng 适合极限压力,自定义 C 工具则能填补所有空白。

4.1 sysbench:系统级基准测试的瑞士军刀

sysbench 这工具,我最早接触是在做数据库性能测试的时候。后来发现它在嵌入式场景下同样好用——CPU、内存、文件 I/O、互斥锁,几乎覆盖了行情系统所有关键子系统的压力测试需求。

4.1.1 安装

在 Ubuntu/Debian 上,一条命令搞定:

sudo apt-get install sysbench

如果是 CentOS/RHEL:

sudo yum install epel-release
sudo yum install sysbench

我个人习惯从源码编译,因为可以控制编译选项,去掉不需要的模块。不过大多数场景下,包管理器安装就够用了。

4.1.2 CPU 测试

行情系统的 CPU 瓶颈通常出现在行情解析和计算环节。用 sysbench 模拟一下:

# 单线程 CPU 测试
sysbench cpu --cpu-max-prime=20000 run

# 多线程测试(模拟多核行情解析)
sysbench cpu --cpu-max-prime=20000 --threads=4 run

输出结果里,重点关注 events per second 这个指标。数值越高,说明 CPU 处理能力越强。我在项目中遇到过,某款 ARM 芯片跑单线程时表现不错,但多线程一上去,性能就断崖式下跌——后来发现是缓存一致性协议的问题。

4.1.3 内存测试

行情数据量大,内存带宽和延迟都很关键:

# 顺序读写测试
sysbench memory --memory-block-size=1M --memory-total-size=10G run

# 随机访问测试
sysbench memory --memory-block-size=1M --memory-total-size=10G --memory-access-mode=rnd run

小技巧:测试内存时,总大小最好设为物理内存的 2-3 倍,这样才能真正压到内存带宽,而不是被缓存糊弄过去。

4.2 perf:性能分析的显微镜

sysbench 告诉你「系统有多快」,perf 则告诉你「为什么慢」。这工具是 Linux 内核自带的性能剖析器,能深入到 CPU 指令级别。

4.2.1 安装

sudo apt-get install linux-tools-common linux-tools-$(uname -r)

嗯,这里要注意:perf 版本必须和内核版本匹配,否则会报错。我曾经在升级内核后忘了同步更新 perf,折腾了半天才发现问题。

4.2.2 基本用法

最常用的场景是统计 CPU 周期和缓存命中率:

# 统计 CPU 周期和指令数
perf stat ./your_application

# 采样分析热点函数
perf record -g ./your_application
perf report

在行情系统优化中,我经常用 perf 来定位「哪行代码最耗 CPU」。有一次发现某个行情解析函数占了 40% 的 CPU 时间,优化后整个系统的吞吐量提升了 30%。

4.2.3 硬件计数器

嵌入式平台通常有丰富的硬件性能计数器:

# 列出所有可用事件
perf list

# 监控缓存未命中
perf stat -e cache-misses,cache-references ./your_application

注意:某些嵌入式芯片(比如低端 ARM Cortex-M 系列)不支持硬件性能计数器。这种情况下,perf 只能做软件事件采样,精度会差一些。

4.3 stress-ng:极限压力测试专家

stress-ng 是 stress 的升级版,支持超过 300 种压力测试场景。对于行情系统,我主要用它来模拟极端负载情况。

4.3.1 安装

sudo apt-get install stress-ng

源码安装也不复杂:

git clone https://github.com/ColinIanKing/stress-ng.git
cd stress-ng
make
sudo make install

4.3.2 常用场景

模拟 CPU 满载:

# 4 个 CPU 核心满载运行 60 秒
stress-ng --cpu 4 --timeout 60s

模拟内存压力:

# 分配 512MB 内存并持续读写
stress-ng --vm 2 --vm-bytes 512M --timeout 30s

模拟 I/O 压力:

# 大量文件读写操作
stress-ng --io 4 --hdd 2 --timeout 30s

我个人习惯把 stress-ng 和 sysbench 配合使用。先用 stress-ng 把系统压到 80% 负载,再用 sysbench 测试行情系统在这种环境下的表现。这样能发现很多「安静环境下测不出来」的问题。

4.4 自定义 C 压测工具:填补空白

现成工具再好,也总有覆盖不到的场景。比如行情系统的特定协议解析、内存池分配模式、锁竞争模式——这些都需要自己写压测工具。

4.4.1 一个简单的 CPU 压测示例

#include <stdio.h>
#include <pthread.h>
#include <time.h>

#define ITERATIONS 100000000

void* cpu_stress(void* arg) {
    volatile double result = 0.0;
    for (long i = 0; i < ITERATIONS; i++) {
        result += i * 3.14159 / (i + 1);
    }
    printf("Result: %f\n", result);
    return NULL;
}

int main() {
    int num_threads = 4;
    pthread_t threads[num_threads];
    
    clock_t start = clock();
    
    for (int i = 0; i < num_threads; i++) {
        pthread_create(&threads[i], NULL, cpu_stress, NULL);
    }
    
    for (int i = 0; i < num_threads; i++) {
        pthread_join(threads[i], NULL);
    }
    
    clock_t end = clock();
    double time_spent = (double)(end - start) / CLOCKS_PER_SEC;
    printf("Total time: %.2f seconds\n", time_spent);
    
    return 0;
}

编译运行:

gcc -O2 -pthread cpu_stress.c -o cpu_stress
./cpu_stress

4.4.2 内存分配压力测试

行情系统频繁分配释放小块内存,很容易产生碎片。我写过一个专门测内存分配延迟的工具:

#include <stdlib.h>
#include <time.h>

#define ALLOC_SIZE 64
#define ALLOC_COUNT 1000000

int main() {
    void* ptrs[ALLOC_COUNT];
    clock_t start = clock();
    
    for (int i = 0; i < ALLOC_COUNT; i++) {
        ptrs[i] = malloc(ALLOC_SIZE);
        if (ptrs[i]) {
            *(volatile char*)ptrs[i] = 0;
        }
    }
    
    for (int i = 0; i < ALLOC_COUNT; i++) {
        free(ptrs[i]);
    }
    
    clock_t end = clock();
    double time_spent = (double)(end - start) / CLOCKS_PER_SEC;
    printf("Allocated %d blocks of %d bytes in %.3f seconds\n",
           ALLOC_COUNT, ALLOC_SIZE, time_spent);
    
    return 0;
}

经验之谈:自定义工具的关键是「可复现」。每次测试前记录系统状态(CPU 频率、内存使用率、进程数),这样不同时间段的测试结果才有可比性。

4.5 工具选择矩阵

为了方便你快速选择,我整理了一个对照表:

测试场景 推荐工具 关键指标 注意事项
CPU 宏观性能 sysbench events/s 注意线程数设置
CPU 热点分析 perf 函数耗时占比 需要内核支持
极限压力测试 stress-ng 系统稳定性 注意散热
特定场景压测 自定义 C 工具 自定义指标 确保可复现
内存带宽 sysbench MB/s 测试量要够大
缓存命中率 perf cache-misses 硬件支持

4.6 工具链集成思路

这些工具不是孤立的。我通常的做法是:

  1. 先用 sysbench 做基线测试,了解系统的基本能力
  2. 再用 stress-ng 制造背景压力,模拟真实环境
  3. 运行行情系统,用 perf 采集性能数据
  4. 针对瓶颈点,写自定义工具做专项测试

举个例子,有一次我发现行情系统在某个 ARM 平台上延迟波动很大。用 perf 一看,发现是 L2 缓存未命中率异常高。再用自定义工具测试不同缓存行大小的分配模式,最终定位到是数据结构对齐问题。修复后,延迟抖动从 30% 降到了 5% 以内。

避坑指南:我曾经在测试时忽略了 CPU 调频的影响。同样的测试,白天和晚上跑出来的结果差了 20%。后来我学会了在测试前固定 CPU 频率:sudo cpupower frequency-set -g performance

好了,工具链就讲到这里。记住,工具只是手段,关键是你要清楚自己在测什么、为什么测。下一章咱们会把这些工具真正用起来,做一个完整的行情系统性能基准测试实战。


公众号:蓝海资料掘金营,微信deep3321