4.5.3. CPU-BPU-DDR 压力测试

4.5.3.1. 测试原理

CPU-BPU-DDR 压力测试测试原理主要涉及对 CPU、 BPU 和 DDR 在高负荷条件性能稳定性进行评估,以下这些组件压力测试一些基本原理:

1. CPU DDR 压力测试

  • 测试目标:使用 stressapptest 工具模拟负载环境,进行大量计算、数据处理内存操作,测试系统多线程并发任务性能。

  • 测试目的:验证 CPU 在长时间负载稳定性性能,确保 CPU 和 DDR 能高负荷运行维持正常工作,避免崩溃、过热性能下降问题。

  • stressapptest CPU 压测原理: CPU 压测主要通过多线程并发执行一些计算密集型任务实现,这些任务包括:计算密集型任务、多线程并行执行等。

    • 线程创建: stressapptest 通过 pthread_create()创建多个线程,每个线程执行计算任务,线程数量通常用户通过 -C 参数指定。

    for (int i = 0; i < num_threads; i++) {
      pthread_create(&threads[i], NULL, cpu_stress_function, (void*)i);
    }
    
    • 计算密集型任务:每个线程执行一些计算密集型操作,例如浮点数计算、内存读写等,这会消耗 CPU 资源。

    void* cpu_stress_function(void* arg) {
      while (true) {
          // Perform some CPU-intensive calculations
          double a = 3.14159265358979;
          for (int i = 0; i < 1000000; i++) {
              a = a * a * 3.14159;  // Simulate a calculation
          }
      }
      return NULL;
    }
    
    • 线程同步管理:通过 pthread_join()函数确保线程正确执行同步。

  • stressapptest DDR 压测原理: DDR 内存 的压力测试涉及大量内存分配、访问数据交换,通过内存使用、频繁内存读写操作、以及内存带宽消耗进行。

    • 内存分配: 在内存压力测试中, stressapptest 会根据 -M 参数(例如 -M 8192 )来分配指定大小内存。

    void* allocate_memory(size_t size) {
      void* ptr = malloc(size);  // 分配指定大小的内存
      if (ptr == NULL) {
          perror("Memory allocation failed");
          exit(1);
      }
      return ptr;
    }
    
    • 内存读写操作 : stressapptest 会分配内存区域进行大量读取写入,以下一个简单内存读写操作例子:

    void stress_memory(void* ptr, size_t size) {
      volatile char* data = (volatile char*)ptr;
          for (size_t i = 0; i < size; i++) {
                  data[i] = (char)(i % 256);  // 写入数据
                  char temp = data[i];  // 读取数据
          }
    }
    
    • 线程访问内存: stressapptest 使用多线程增加内存压力。多个线程并发内存进行访问,模拟负载内存使用情况。

  • 命令分析:运行压测脚本后,运行如下命令: stressapptest -s "$stime" -M "$memory_size" -f /tmp/sat.io1 -f /tmp/sat.io2 -i "$io_threads" -m 8 -C 2 -W

    • -s "$stime": 这个参数指定了 测试持续时间。

    • -M "$memory_size”: 这个参数指定内存使用量,在源码中,-M 参数用于控制内存分配大小。

    • -f /tmp/sat.io1 -f /tmp/sat.io2: -f 参数用于指定文件用于 I/O 测试。

    • -i "$io_threads": 该参数指定用于 I/O 操作线程数。

    • -m 8: 这个参数控制 内存压力强度。

    • -C 2: 这个参数指定进行压力测试使用的 CPU 核心数。

    • -W: 这个参数启用了 写操作,意味着不仅进行内存读取,还会进行写入操作。

2. BPU 压力测试

  • 测试目标: 通过运行 run-portion.sh 脚本,并利用 tc_hbdk3 工具调整 -b ( BPU 核心 )和 -p( BPU 负载比例 )参数,模拟不同的 BPU 负载场景,确保 BPU 在负载依然能够稳定工作达到预期性能。

  • 测试目的:确保 BPU 在执行计算任务时,能够输出预期相符正确结果,检查 BPU 长时间负载运行稳定工作,不出现崩溃错误。

  • tc_hbdk3 BPU 压测原理: 通过加载包含大量计算任务模型,利用 BPU 进行加速计算,从而实现对 BPU 的压力测试。

  • 命令分析: 运行压测脚本后,运行如下命令:tc_hbdk3 -t $1 -b $2 -f $HBM_FILE -i $SRC_FILE -n $MODEL_NAME -o $OUTPUT_0_0,$OUTPUT_0_1,$OUTPUT_1_0,$OUTPUT_1_1 -g 0 -c 0

    • -t $1 : 传递 $portion 参数值,可以灵活控制压力测试强度,并且可以根据不同测试需求选择合适负载水平。

    • -b $2 : 选择使用的 BPU 核心数。

    • -f $HBM_FILE:-f 参数指定了 HBM 文件。

    • -i $SRC_FILE: 该文件包含模型推理训练使用输入数据,程序从中读取数据传递给 BPU 进行计算。

    • -n $MODEL_NAME: -n 参数指定加载运行的 模型名称

    • -o $OUTPUT_0_0 : 这些输出文件用于保存计算结果日志数据。

4.5.3.2. 准备工作

1. 开始压力测试前,需要芯片添加散热片,否则芯片可能进入过温保护影响测试结果。

2. 确认在 /app/platform_samples/chip_base_test/01_cpu_bpu_ddr 路径存在文件是否完整:

01_cpu_bpu_ddr/
├── models
│   └── HBDK3_MODEL_2K
│       ├── input_0_feature_1x1088x2048x3_ddr_native.bin
│       ├── run.sh
│       └── x5
│           └── gen_I2004_ForTest2k_1x1088x2048x3.hbm
├── scripts
│   ├── run-portion.sh
│   ├── stop_test.sh
│   ├── stress_test.sh
│   └── stressapptest
└── tc_hbdk3

4.5.3.3. 测试方法

压测脚本支持输入后缀 -h 查看命令参数说明 :

./stress_test.sh -h

Usage: ./stress_test.sh [options]

Options:
  -t <time>        Set the test duration (e.g., 2h for hours, 30m for minutes; default: 48h).
  -m <size>        Set the memory size for stress test in MB (default: 100).
  -i <threads>     Set the I/O threads for stress test (default: 4).
  -b <bpu_core>    Specify the BPU core to use (default: 0).
  -p <portion>     Set the BPU portion value (default: 100).
  -o <directory>   Set the output directory for logs (default: ../../log).
  -h, --help       Show this help message and exit.

Example:
  ./stress_test.sh -t 24h -m 200 -i 8 -p 80

参数解析如下:

  • t <time>: 用于设置压力测试持续时间 , 时间格式可以小时(如 2h)或分钟(如 30m),默认值为 48 小时。

  • m <size>: 用于设置压力测试内存大小(单位: MB),默认值为 100MB。

  • i <threads>: 用于设置 I/O 线程数量,默认值为 4 。

  • b <bpu_core>: 用于指定 BPU(基于处理单元)核心编号,默认值为 0 。

  • p <portion>: 用于设置 BPU 负载比例,默认值为 100 (即满负载)。

  • o <directory>: 用于设置日志输出目录,默认值为 ../../log。

  • h, --help: 显示帮助信息退出脚本。

示例: 例如,使用命令 ./stress_test.sh -t 24h -m 200 -i 8 -p 80运行一个 24 小时压力测试,使用 200MB 内存, 8 个 I/O 线程, 80% 的 BPU 负载。

确保完成准备工作后,运行测试命令:

cd /app/platform_samples/chip_base_test/01_cpu_bpu_ddr/scripts

./stress_test.sh

压测脚本通过 hrut_somstatus 命令监控 stressapptest运行情况,运行脚本启动日志如下:

Running stress test with the following configuration:
  Stress Time: 48h hours (2880 seconds)
  Memory Size: 100 MB
  I/O Threads: 4
  BPU Core: 0
  BPU Portion: 100%
  Output directory: /app/platform_samples/chip_base_test/log
Starting CPU stress test...
nohup: redirecting stderr to stdout
Starting BPU stress test...
=====================1=====================
temperature-->
        DDR      : 84.0 (C)
83087
        BPU      : 82.9 (C)
        CPU      : 83.7 (C)
cpu frequency-->
              min(M)    cur(M)  max(M)
        cpu0: 300       1500    1500
        cpu1: 300       1500    1500
        cpu2: 300       1500    1500
        cpu3: 300       1500    1500
        cpu4: 300       1500    1500
        cpu5: 300       1500    1500
        cpu6: 300       1500    1500
        cpu7: 300       1500    1500
bpu status information---->
              min(M)    cur(M)  max(M)  ratio
        bpu0: 500       1000    1000    98
ddr frequency information---->
              min(M)    cur(M)  max(M)
        ddr:  266       4266    4266
GPU gc8000 frequency information---->
              min(M)    cur(M)  max(M)
        gc8000:  200    1000    1000

hrut_somstatus 命令结果解析如下:

  • temperature :代表当前 DDR、 BPU、 CPU 的温度。

  • cpu frequency :分别代表 CPU 0-7 的最小运行频率、当前运行频率最大运行频率( MHZ)。

  • bpu status information :代表 BPU 的最小、当前最大运行频率,其中 ratio 代表 BPU 当前占用率。

执行 top 命令查看 CPU占用率

image-20240313201614942

其中一行显示一个 CPU 核心状态,格式为:

%CpuX  :  user/system  idle [ 进度条 ]
  • %CpuX:表示 CPU 核心编号,例如 %Cpu0 表示第 0 核心。

  • user:该核心的 CPU 时间中,有多少比例用于执行用户空间进程(如应用程序、进程等)。

  • system:该核心的 CPU 时间中,有多少比例用于执行内核空间进程(内核操作)。

  • idle:该核心多少时间空闲的, cpu0 当前空闲为 1 。

  • 进度条:显示核心负载情况。每个进度条长度反映了 CPU 的负载强度。

例如第一个核心 %Cpu0 , 50.8% 的时间执行用户进程, 48.7% 的时间执行内核操作(系统进程),空闲时间为 0%,即该核心几乎没有空闲时间。

4.5.3.4. 测试指标

测试程序启动后,会/app/platform_samples/chip_base_test/log 目录产生 bpu-stressX.logcpu-stressX.log 两份日志文件用来记录测时状态,确保能够压测保持如下内容:

  • 稳定运行 48 小时,不出现重启情况。

  • 使用以下命令检查日志文件是否存在 failerrortimeout异常打印。

cd "/app/platform_samples/chip_base_test/log/" && grep -iE 'error|fail|timeout' bpu-stress*.log cpu-stress*.log
  • 执行 TOP 命令查看 CPU、 BPU 占情况,正常状态稳定保持在 98-100% 区间。

测试结果

输入命令:

cd "/app/platform_samples/chip_base_test/log/" && grep -iE 'error|fail|timeout' bpu-stress*.log cpu-stress*.log

显示如下:

cpu-stress1.log:1970/01/01-02:11:11(UTC) Stats: Completed: 80944.00M in 14.24s 5685.54MB/s, with 0 hardware incidents, 0 errors
cpu-stress1.log:1970/01/01-02:11:11(UTC) Status: PASS - please verify no corrected errors
cpu-stress2.log:1970/01/01-00:10:29(UTC) Stats: Completed: 3300956.00M in 589.29s 5601.62MB/s, with 0 hardware incidents, 0 errors
cpu-stress2.log:1970/01/01-00:10:29(UTC) Status: PASS - please verify no corrected errors
cpu-stress3.log:1970/01/01-00:34:09(UTC) Stats: Completed: 236090.00M in 44.79s 5270.69MB/s, with 0 hardware incidents, 0 errors
cpu-stress3.log:1970/01/01-00:34:09(UTC) Status: PASS - please verify no corrected errors

打印信息并未出现其他异常信息,且 errors 数量为 0 ,代表压测结果正常。