[单片机芯片] CH32V307浮点指令生成测试

[复制链接]
 楼主| zhanzr21 发表于 2023-9-16 21:32 | 显示全部楼层 |阅读模式
#申请原创#
IMG_20230910_155617548.jpg
CH32V307芯片的内核是QinkeV4F,带有FPU.
做个代码测试一下子FPU指令相对于软浮点代码的效率对比.

测试代码:
  1. #include <stdint.h>

  2. #define TEST_CNT    1000000

  3. float test_float(void) {
  4.     float sum = 0.1;

  5.     for(uint32_t i=0; i < TEST_CNT; ++i) {
  6.         sum += 0.625;
  7.     }

  8.     return sum;
  9. }

  10. double test_double(void) {
  11.     double sum = 0.1;

  12.     for(uint32_t i=0; i < TEST_CNT; ++i) {
  13.         sum += 0.625;
  14.     }

  15.     return sum;
  16. }
  1. {
  2.             uint32_t s_ticks = g_ticks;
  3.             float result = test_float();
  4.             uint32_t e_ticks = g_ticks;
  5.             printf( "%u - %u\r\n", s_ticks, e_ticks);
  6.             printf( "%f, test duration %u\r\n", result, e_ticks - s_ticks);
  7.         }

  8.         {
  9.             uint32_t s_ticks = g_ticks;
  10.             double result = test_double();
  11.             uint32_t e_ticks = g_ticks;
  12.             printf( "%u - %u\r\n", s_ticks, e_ticks);
  13.             printf( "%f, double duration %u\r\n", result, e_ticks - s_ticks);
  14.         }
通过配置是否使用FPU来对比运行效率,主要是这两个配置选项:
566866505ac31cbcda.png
运行结果:
使用了FPU指令:
  1. 625000.125000, test duration 41
  2. 625000.100000, double duration 1186
不使用FPU指令,软件模拟浮点运算:
  1. 625000.125000, test duration 763
  2. 625000.100000, double duration 1031
结论:
单精度情况下, 硬件FPU指令比软件浮点快近19倍.
763/41 = 18.609756097560975

对于双精度情况, 由于都是软件模拟, 所以性能近似.
那么为什么, 使用软件模拟浮点运算时, 双精度的性能要稍稍提升一点.( 1186/1131 = 1.0486295313881522, 约5个百分点的提升).
本人认为是单精度与双精度都使用了软件模拟运算, 某些共通部分有一些编译器与连接器带来的优化效果.

最后看看两种情况下生成的代码差异.
1. 硬件FPU:
  1.    4                      .Ltext0:
  2.    5                              .cfi_sections        .debug_frame
  3.    6                              .section        .text.test_float,"ax",@progbits
  4.    7                              .align        1
  5.    8                              .globl        test_float
  6.   10                      test_float:
  7.   11                      .LFB0:
  8.   12                              .file 1 "../User/test_float_double.c"
  9.    1:../User/test_float_double.c **** /*
  10.    2:../User/test_float_double.c ****  * test_float_double.c
  11.    3:../User/test_float_double.c ****  *
  12.    4:../User/test_float_double.c ****  *  Created on: Sep 16, 2023
  13.    5:../User/test_float_double.c ****  *      Author: Administrator
  14.    6:../User/test_float_double.c ****  */
  15.    7:../User/test_float_double.c **** #include <stdint.h>
  16.    8:../User/test_float_double.c ****
  17.    9:../User/test_float_double.c **** #define TEST_CNT    1000000
  18.   10:../User/test_float_double.c ****
  19.   11:../User/test_float_double.c **** float test_float(void) {
  20.   13                              .loc 1 11 24
  21.   14                              .cfi_startproc
  22.   12:../User/test_float_double.c ****     float sum = 0.1;
  23.   15                              .loc 1 12 5
  24.   16                      .LVL0:
  25.   13:../User/test_float_double.c ****
  26.   14:../User/test_float_double.c ****     for(uint32_t i=0; i < TEST_CNT; ++i) {
  27.   17                              .loc 1 14 5
  28.   18                      .LBB2:
  29.   19                              .loc 1 14 9
  30.   20                      .LBE2:
  31.   12:../User/test_float_double.c ****     float sum = 0.1;
  32.   21                              .loc 1 12 11 is_stmt 0
  33.   22 0000 B7070000                 lui        a5,%hi(.LC0)
  34.   23 0004 07A50700                 flw        fa0,%lo(.LC0)(a5)
  35.   24                      .LBB3:
  36.   15:../User/test_float_double.c ****         sum += 0.625;
  37.   25                              .loc 1 15 13
  38.   26 0008 B7070000                 lui        a5,%hi(.LC1)
  39.   27 000c 87A70700                 flw        fa5,%lo(.LC1)(a5)
  40.   28                      .LBE3:
  41.   11:../User/test_float_double.c ****     float sum = 0.1;
  42.   29                              .loc 1 11 24
  43.   30 0010 B7470F00                 li        a5,999424
  44.   31 0014 93870724                 addi        a5,a5,576
  45.   32                      .LVL1:
  46.   33                      .L2:
  47.   34                      .LBB4:
  48.   35                              .loc 1 15 9 is_stmt 1 discriminator 3
  49.   36 0018 FD17                     addi        a5,a5,-1
  50.   37                              .loc 1 15 13 is_stmt 0 discriminator 3
  51.   38 001a 5375F500                 fadd.s        fa0,fa0,fa5
  52.   39                      .LVL2:
  53.   14:../User/test_float_double.c ****         sum += 0.625;
  54.   40                              .loc 1 14 5 discriminator 3
  55.   41 001e EDFF                     bnez        a5,.L2
  56.   42                      .LBE4:
  57.   16:../User/test_float_double.c ****     }
  58.   17:../User/test_float_double.c ****
  59.   18:../User/test_float_double.c ****     return sum;
  60.   19:../User/test_float_double.c **** }
  61.   43                              .loc 1 19 1
  62.   44 0020 8280                     ret
  63.   45                              .cfi_endproc
2.软件模拟FPU:
  1.    4                      .Ltext0:
  2.    5                              .cfi_sections        .debug_frame
  3.    6                              .globl        __addsf3
  4.    7                              .section        .text.test_float,"ax",@progbits
  5.    8                              .align        1
  6.    9                              .globl        test_float
  7.   11                      test_float:
  8.   12                      .LFB0:
  9.   13                              .file 1 "../User/test_float_double.c"
  10.    1:../User/test_float_double.c **** /*
  11.    2:../User/test_float_double.c ****  * test_float_double.c
  12.    3:../User/test_float_double.c ****  *
  13.    4:../User/test_float_double.c ****  *  Created on: Sep 16, 2023
  14.    5:../User/test_float_double.c ****  *      Author: Administrator
  15.    6:../User/test_float_double.c ****  */
  16.    7:../User/test_float_double.c **** #include <stdint.h>
  17.    8:../User/test_float_double.c ****
  18.    9:../User/test_float_double.c **** #define TEST_CNT    1000000
  19.   10:../User/test_float_double.c ****
  20.   11:../User/test_float_double.c **** float test_float(void) {
  21.   14                              .loc 1 11 24
  22.   15                              .cfi_startproc
  23.   16 0000 17030000                 call        t0,__riscv_save_2
  24.   16      E7020300
  25.   17                              .cfi_offset 9, -12
  26.   18                              .cfi_offset 8, -8
  27.   19                              .cfi_offset 1, -4
  28.   20                              .cfi_def_cfa_offset 16
  29.   12:../User/test_float_double.c ****     float sum = 0.1;
  30.   21                              .loc 1 12 5
  31.   22                      .LVL0:
  32.   13:../User/test_float_double.c ****
  33.   14:../User/test_float_double.c ****     for(uint32_t i=0; i < TEST_CNT; ++i) {
  34.   23                              .loc 1 14 5
  35.   24                      .LBB2:
  36.   25                              .loc 1 14 9
  37.   26                      .LBE2:
  38.   12:../User/test_float_double.c ****     float sum = 0.1;
  39.   27                              .loc 1 12 11 is_stmt 0
  40.   28 0008 B7070000                 lui        a5,%hi(.LC0)
  41.   29                      .LBB3:
  42.   15:../User/test_float_double.c ****         sum += 0.625;
  43.   30                              .loc 1 15 13
  44.   31 000c 37070000                 lui        a4,%hi(.LC1)
  45.   32                      .LBE3:
  46.   12:../User/test_float_double.c ****     float sum = 0.1;
  47.   33                              .loc 1 12 11
  48.   34 0010 83A70700                 lw        a5,%lo(.LC0)(a5)
  49.   35                      .LBB4:
  50.   36                              .loc 1 15 13
  51.   37 0014 83240700                 lw        s1,%lo(.LC1)(a4)
  52.   38                      .LBE4:
  53.   11:../User/test_float_double.c ****     float sum = 0.1;
  54.   39                              .loc 1 11 24
  55.   40 0018 37440F00                 li        s0,999424
  56.   41 001c 13040424                 addi        s0,s0,576
  57.   42                      .LVL1:
  58.   43                      .L2:
  59.   44                      .LBB5:
  60.   45                              .loc 1 15 9 is_stmt 1 discriminator 3
  61.   46                              .loc 1 15 13 is_stmt 0 discriminator 3
  62.   47 0020 3E85                     mv        a0,a5
  63.   48 0022 A685                     mv        a1,s1
  64.   49 0024 97000000                 call        __addsf3
  65.   49      E7800000
  66.   50                      .LVL2:
  67.   51 002c 7D14                     addi        s0,s0,-1
  68.   52 002e AA87                     mv        a5,a0
  69.   53                      .LVL3:
  70.   14:../User/test_float_double.c ****         sum += 0.625;
  71.   54                              .loc 1 14 5 discriminator 3
  72.   55 0030 65F8                     bnez        s0,.L2
  73.   56                      .LBE5:
  74.   16:../User/test_float_double.c ****     }
  75.   17:../User/test_float_double.c ****
  76.   18:../User/test_float_double.c ****     return sum;
  77.   19:../User/test_float_double.c **** }
  78.   57                              .loc 1 19 1
  79.   58 0032 17030000                 tail        __riscv_restore_2
  80.   58      67000300
  81.   59                              .cfi_restore 9
  82.   60                              .cfi_restore 8
  83.   61                              .cfi_restore 1
  84.   62                              .cfi_def_cfa_offset 0
  85.   63                              .cfi_endproc
可以看出硬件FPU计算时, 有明显的浮点指令:
  1. fadd.s        fa0,fa0,fa5
谢谢阅读.

tpgf 发表于 2024-3-1 15:46 | 显示全部楼层
能接收的最复杂的运算是什么呢
观海 发表于 2024-3-1 18:12 | 显示全部楼层
这个速度快慢是如何体现出来的呢
八层楼 发表于 2024-3-1 18:43 | 显示全部楼层
请问什么叫做浮点指令生成啊?难道不是固定的指令吗
guanjiaer 发表于 2024-3-2 08:00 | 显示全部楼层
软件模拟那部分代码我都没看明白  是什么语言啊
heimaojingzhang 发表于 2024-3-2 08:31 | 显示全部楼层
可以单独为浮点数运算开辟 一个线程吗
keaibukelian 发表于 2024-3-2 09:02 | 显示全部楼层
可以开启这个功能做普通的运算吗?
 楼主| zhanzr21 发表于 2024-3-31 18:02 | 显示全部楼层
keaibukelian 发表于 2024-3-2 09:02
可以开启这个功能做普通的运算吗?

可以的, 就看你运算是否涉及浮点, 如果不涉及浮点, 则开启了也没有加速的.
 楼主| zhanzr21 发表于 2024-3-31 18:02 | 显示全部楼层
heimaojingzhang 发表于 2024-3-2 08:31
可以单独为浮点数运算开辟 一个线程吗

可以, 看你应用是否有大量需要浮点运算的功能.
 楼主| zhanzr21 发表于 2024-3-31 18:03 | 显示全部楼层
guanjiaer 发表于 2024-3-2 08:00
软件模拟那部分代码我都没看明白  是什么语言啊

汇编语言
 楼主| zhanzr21 发表于 2024-3-31 18:04 | 显示全部楼层
八层楼 发表于 2024-3-1 18:43
请问什么叫做浮点指令生成啊?难道不是固定的指令吗

请看我的贴图.

就是测试在是否打开浮点指令开关的差别, 如果打开了就会生成单精度FPU指令生成, 否则使用软件模拟.
 楼主| zhanzr21 发表于 2024-3-31 18:04 | 显示全部楼层
观海 发表于 2024-3-1 18:12
这个速度快慢是如何体现出来的呢

相同的计算, 使用定时器观察所耗时间
 楼主| zhanzr21 发表于 2024-3-31 18:05 | 显示全部楼层
tpgf 发表于 2024-3-1 15:46
能接收的最复杂的运算是什么呢

仅受内存大小限制
caigang13 发表于 2024-4-1 08:20 来自手机 | 显示全部楼层
RISC-V内核的芯片?

评论

是的  发表于 2024-4-3 17:05
LEDyyds 发表于 2024-4-25 13:15 | 显示全部楼层
那个配置FPU 的软件是啥
 楼主| zhanzr21 发表于 2024-5-27 15:17 | 显示全部楼层
LEDyyds 发表于 2024-4-25 13:15
那个配置FPU 的软件是啥

就是官方配套的开发IDE,在项目属性里配置
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:每天都進步

91

主题

1017

帖子

34

粉丝
快速回复 在线客服 返回列表 返回顶部