在 ST 官网上查看 MCU 的介绍时,经常会看到下面的数据,例如 STM32F103的介绍:






上面的 1.25 DMIPS/MHz 代表什么意思,又是如何得到的呢?这就是 CPU 性能测试 (benchmark) 小工具 Dhrystone 测试得到的。
Dhrystone
Dhrystone 是 1984 年由 Reinhold P. Weicker 提出的通用处理器 (CPU) 性能测试标准,最早用 ADA 实现,随后 Rick Richardson 把它翻译为 C 语言,并很快成为了业界标准。不过 Dhdrystone 只测试整型运算,并不包含浮点运算,因此无法用它来判断 FPU 的性能。
最新的源码可以在这里:https://www.netlib.org/benchmark/dhry-c 找到,虽说是最新,其实也有几十年历史了,这个链接里不仅包含了介绍,也可以直接生成源码:


1$ curl https://www.netlib.org/benchmark/dhry-c > dhry-c.sh
2$ chmod u+x dhry-c.sh
3$ ./dhry-c.sh
这样就可以看到目录下生成了源码和介绍了:


1.
2├── RATIONALE
3├── README_C
4├── VARIATIONS
5├── dhry-c.sh
6├── dhry.h
7├── dhry_1.c
8├── dhry_2.c
9├── dhry_c.dif
10└── submit.frm
当然,如果是在 RT-Thread 平台的话,直接在 env 下面 menuconfig 就可以找到 Dhrystone 软件包了:
1RT-Thread online packages
2  tools packages  --->
3      
  • DHRYSTONE: a benchmark that measures the performance of MCUs and CPUs.
    选中软件包并编译,就可以在 msh 下输入:


    1msh> dhrystone_test
    就可以看到跑分结果了,例如:
    STM32F103 (ARMCC -O3 -Otime) 跑分: 79 DMIPS & 1.09 DMIPS/MHz
    1 \ | /
    2- RT -     Thread Operating System
    3 / | \     4.0.2 build Oct 15 2019
    4 2006 - 2019 Copyright by rt-thread team
    5msh >
    6msh >dhrystone_test
    7
    8Dhrystone Benchmark, Version 2.1 (Language: C)
    9
    10Program compiled without 'register' attribute
    11
    12Execution starts, 320000 runs through Dhrystone
    13Execution ends
    14
    15Final values of the variables used in the benchmark:
    16
    17Int_Glob:            5
    18        should be:   5
    19Bool_Glob:           1
    20        should be:   1
    21Ch_1_Glob:           A
    22        should be:   A
    23Ch_2_Glob:           B
    24        should be:   B
    25Arr_1_Glob[8]:       7
    26        should be:   7
    27Arr_2_Glob[8][7]:    320010
    28        should be:   Number_Of_Runs + 10
    29Ptr_Glob->
    30  Ptr_Comp:          536892000
    31        should be:   (implementation-dependent)
    32  Discr:             0
    33        should be:   0
    34  Enum_Comp:         2
    35        should be:   2
    36  Int_Comp:          17
    37        should be:   17
    38  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
    39        should be:   DHRYSTONE PROGRAM, SOME STRING
    40Next_Ptr_Glob->
    41  Ptr_Comp:          536892000
    42        should be:   (implementation-dependent), same as above
    43  Discr:             0
    44        should be:   0
    45  Enum_Comp:         1
    46        should be:   1
    47  Int_Comp:          18
    48        should be:   18
    49  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
    50        should be:   DHRYSTONE PROGRAM, SOME STRING
    51Int_1_Loc:           5
    52        should be:   5
    53Int_2_Loc:           13
    54        should be:   13
    55Int_3_Loc:           7
    56        should be:   7
    57Enum_Loc:            1
    58        should be:   1
    59Str_1_Loc:           DHRYSTONE PROGRAM, 1'ST STRING
    60        should be:   DHRYSTONE PROGRAM, 1'ST STRING
    61Str_2_Loc:           DHRYSTONE PROGRAM, 2'ND STRING
    62        should be:   DHRYSTONE PROGRAM, 2'ND STRING
    63
    64Microseconds for one run through Dhrystone: 7
    65Dhrystones per Second:                      139130
    66VAX  MIPS rating:                           79
    GD32VF103CB (GCC -Os) 跑分: 50 DMIPS & 0.46 DMIPS/MHz
    1 \ | /
    2- RT -     Thread Operating System
    3 / | \     4.0.2 build Oct 14 2019
    4 2006 - 2019 Copyright by rt-thread team
    5msh >
    6msh >dhrystone_test
    7
    8Dhrystone Benchmark, Version 2.1 (Language: C)
    9
    10Program compiled without 'register' attribute
    11
    12Execution starts, 320000 runs through Dhrystone
    13Execution ends
    14
    15Final values of the variables used in the benchmark:
    16
    17Int_Glob:            5
    18        should be:   5
    19Bool_Glob:           1
    20        should be:   1
    21Ch_1_Glob:           A
    22        should be:   A
    23Ch_2_Glob:           B
    24        should be:   B
    25Arr_1_Glob[8]:       7
    26        should be:   7
    27Arr_2_Glob[8][7]:    320010
    28        should be:   Number_Of_Runs + 10
    29Ptr_Glob->
    30  Ptr_Comp:          536884636
    31        should be:   (implementation-dependent)
    32  Discr:             0
    33        should be:   0
    34  Enum_Comp:         2
    35        should be:   2
    36  Int_Comp:          17
    37        should be:   17
    38  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
    39        should be:   DHRYSTONE PROGRAM, SOME STRING
    40Next_Ptr_Glob->
    41  Ptr_Comp:          536884636
    42        should be:   (implementation-dependent), same as above
    43  Discr:             0
    44        should be:   0
    45  Enum_Comp:         1
    46        should be:   1
    47  Int_Comp:          18
    48        should be:   18
    49  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
    50        should be:   DHRYSTONE PROGRAM, SOME STRING
    51Int_1_Loc:           5
    52        should be:   5
    53Int_2_Loc:           13
    54        should be:   13
    55Int_3_Loc:           7
    56        should be:   7
    57Enum_Loc:            1
    58        should be:   1
    59Str_1_Loc:           DHRYSTONE PROGRAM, 1'ST STRING
    60        should be:   DHRYSTONE PROGRAM, 1'ST STRING
    61Str_2_Loc:           DHRYSTONE PROGRAM, 2'ND STRING
    62        should be:   DHRYSTONE PROGRAM, 2'ND STRING
    63
    64Microseconds for one run through Dhrystone: 11
    65Dhrystones per Second:                      89385
    66VAX  MIPS rating:                           50
    顺便一提,如果没有看到测试结果,可能是你的 MCU 太强劲了,一下就跑完了所有的测试,以至于没有得到有效的结果;或者 msh 控制台卡死很久没有得到结果,多半是你的 MCU 太慢了。这种情况下都可以修改 menuconfig 里的迭代次数,来匹配你的 MCU。更多测试结果可以在下面的参考资料里找到。
    参考资料
    Dhrystone 软件包:


    https://github.com/wuhanstudio/dhrystone


    Dhrystone 测试结果汇总:


    http://performance.netlib.org/performance/html/dhrystone.data.col0.html


    Dhrystone 历史源码:


    https://github.com/Keith-S-Thompson/dhrystone


    Coremark
    虽然在 ST 的官网上都会放有 Dhrystone 的测试结果,但是不得不说作为一个历史悠久的性能测试工具,它还是有很多弊端的,为此 eembc 推出了新的性能测试工具 Coremark,相比 Dhrystone 有不少改进:






    Coremark 的主页可以在这里: https://www.eembc.org/coremark/ 找到,上面 Coremark 相比 Dhrystone 优点的截图也是从官网截取的,当然也可以从官网上找到最新的源码和测试结果。 当然,如果是在 RT-Thread 平台的话,直接在 env 下面 menuconfig 就可以找到 Coremark 软件包了:
    1RT-Thread online packages
    2  tools packages  --->
    3      
  • COREMARK : a benchmark that measures the performance of MCUs and CPUs.
    选中软件包并编译,就可以在 msh 下输入:


    1msh> core_mark
    就可以看到跑分结果了,例如: STM32F103RC (72MHZ) ARMCC -O3 -Otime 跑分 135:
    1 \ | /
    2- RT -     Thread Operating System
    3 / | \     4.0.2 build Oct 13 2019
    4 2006 - 2019 Copyright by rt-thread team
    5msh >
    6msh >core_mark
    7Benchmark started, please make sure it runs for at least 10s.
    8
    92K performance run parameters for coremark.
    10CoreMark Size    : 666
    11Total ticks      : 17776
    12Total time (secs): 17.77600013Iterations/Sec   : 135.01350114Iterations       : 240015Compiler version : Please put compiler version here (e.g. gcc 4.1)16Compiler flags   :17Memory location  : STACK18seedcrc          : 0xe9f519[0]crclist       : 0xe71420[0]crcmatrix     : 0x1fd721[0]crcstate      : 0x8e3a22[0]crcfinal      : 0x382f23Correct operation validated. See README.md for run and reporting rules.24CoreMark 1.0 : 135.013501 / Please put compiler version here (e.g. gcc 4.1)  / STACK25
    GD32VF103 (108MHz) GCC -Os 跑分 327:


    1 \ | /
    2- RT -     Thread Operating System
    3 / | \     4.0.2 build Oct 13 2019
    4 2006 - 2019 Copyright by rt-thread team
    5msh >
    6msh >core_mark
    7Benchmark started, please make sure it runs for at least 10s.
    8
    92K performance run parameters for coremark.
    10CoreMark Size    : 666
    11Total ticks      : 1178
    12Total time (secs): 1113Iterations/Sec   : 32714Iterations       : 360015Compiler version : GCC8.2.016Compiler flags   :17Memory location  : STACK18seedcrc          : 0xe9f519[0]crclist       : 0xe71420[0]crcmatrix     : 0x1fd721[0]crcstate      : 0x8e3a22[0]crcfinal      : 0x4bfc23Correct operation validated. See README.md for run and reporting rules.24CoreMark 1.0 : 327 / GCC8.2.0  / STACK25
    最终得分当然是越高越好了,为了得到有效的测试结果,需要确保测试运行 10s 以上,可以修改 menuconfig 里的迭代次数,来匹配你的 MCU。更多测试结果可以在官网里找到。


    参考资料
    Coremark 软件包:


    https://github.com/wuhanstudio/coremark


    Coremark 测试结果汇总:


    https://www.eembc.org/coremark/scores.php


    Coremark 官网:


    https://www.eembc.org/coremark/


    注意事项
    不得不说,无论是 Dhrystone 还是 Coremark,编译器的优化选项对测试结果影响都是比较大的,如果你的测试结果与官网的结果略有不同,可以看看是不是自己没有打开编译器的优化选项。