OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2701|回复: 3

使用SIMD指令usub8,sel加速strlen

[复制链接]

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
发表于 2020-2-15 17:09:24 | 显示全部楼层 |阅读模式
本帖最后由 sppz 于 2020-10-17 09:38 编辑

先看一usub8的行为
a.png
可以看到字节溢出则对应的GE位为0
APSR情况如下
1.png
字节值下溢时为0对应GE为0再看一下sel行为
b.png
通过GE又可以选择该字节的值,这里我们GE=1时0,GE=0时选择1,这样有'\0'时,值才会不为0

代码如下(未经验证),如果有人试了有问题,请告诉我,谢谢
  1. size_t strlen(const char *string)
  2. {
  3.     const char *data;
  4.     size_t value0, value1, value2;

  5.     data = string;
  6.     while (((size_t)data) % sizeof(void *) != 0)
  7.     {
  8.         if (*data == '\0')
  9.         {
  10.             return data - string;
  11.         }
  12.         ++data;
  13.     }
  14.     value1 = 0x01010101, value2 = 0;
  15.     __asm__(
  16.         "__loop:;\n"
  17.         "ldr %[value0], [%[data]], #4;\n"
  18.         "usub8 %[value0], %[value0], %[value1];\n"
  19.         "sel %[result],  %[value2], %[value1];\n"
  20.         "cmp %[result], #0;\n"
  21.         "beq __loop;\n"
  22.         : [result]"=r" (value0)
  23.         : [data]"r" (data), [value0]"r" (value0), [value1]"r" (value1), [value2]"r" (value2)
  24.         :
  25.     );
  26.     if ((value0 & 0xff) != 0)
  27.     {
  28.         return data - string - 4;
  29.     }
  30.     else if ((value0 & 0xff00) != 0)
  31.     {
  32.         return data - string - 3;
  33.     }
  34.     else if ((value0 & 0xff0000) != 0)
  35.     {
  36.         return data - string - 2;
  37.     }
  38.     else
  39.     {
  40.         return data - string - 1;
  41.     }
  42. }
复制代码



附加汇编,可以看出关键部分效率应该还是很高的
  1. 08000dc0 strlen:
  2. 8000dc0: 81 07                                lsls        r1, r0, #30
  3. 8000dc2: 01 46                                mov        r1, r0
  4. 8000dc4: 1a d0                                beq        #52 <__loop+0x30>
  5. 8000dc6: 4f f0 01 32                          mov.w        r2, #16843009
  6. 8000dca: 00 23                                movs        r3, #0

  7. 08000dcc __loop:
  8. 8000dcc: 51 f8 04 0b                          ldr        r0, [r1], #4
  9. 8000dd0: c0 fa 42 f0                          usub8        r0, r0, r2
  10. 8000dd4: a3 fa 82 f2                          sel        r2, r3, r2
  11. 8000dd8: 00 2a                                cmp        r2, #0
  12. 8000dda: f7 d0                                beq        #-18 <__loop>
  13. 8000ddc: 08 1a                                subs        r0, r1, r0
  14. 8000dde: 13 06                                lsls        r3, r2, #24
  15. 8000de0: 1c bf                                itt        ne
  16. 8000de2: 04 38                                subne        r0, #4
  17. 8000de4: 70 47                                bxne        lr
  18. 8000de6: 12 f4 7f 4f                          tst.w        r2, #65280
  19. 8000dea: 1c bf                                itt        ne
  20. 8000dec: 03 38                                subne        r0, #3
  21. 8000dee: 70 47                                bxne        lr
  22. 8000df0: 12 f4 7f 0f                          tst.w        r2, #16711680
  23. 8000df4: 14 bf                                ite        ne
  24. 8000df6: 02 38                                subne        r0, #2
  25. 8000df8: 01 38                                subeq        r0, #1
  26. 8000dfa: 70 47                                bx        lr
  27. 8000dfc: 01 78                                ldrb        r1, [r0]
  28. 8000dfe: 02 46                                mov        r2, r0
  29. 8000e00: a1 b1                                cbz        r1, #40
  30. 8000e02: 51 1c                                adds        r1, r2, #1
  31. 8000e04: 8b 07                                lsls        r3, r1, #30
  32. 8000e06: de d1                                bne        #-68 <strlen+0x6>
  33. 8000e08: 0b 78                                ldrb        r3, [r1]
  34. 8000e0a: 8b b1                                cbz        r3, #34
  35. 8000e0c: 91 1c                                adds        r1, r2, #2
  36. 8000e0e: 8b 07                                lsls        r3, r1, #30
  37. 8000e10: d9 d1                                bne        #-78 <strlen+0x6>
  38. 8000e12: 0b 78                                ldrb        r3, [r1]
  39. 8000e14: 63 b1                                cbz        r3, #24
  40. 8000e16: d1 1c                                adds        r1, r2, #3
  41. 8000e18: 8b 07                                lsls        r3, r1, #30
  42. 8000e1a: d4 d1                                bne        #-88 <strlen+0x6>
  43. 8000e1c: 0b 78                                ldrb        r3, [r1]
  44. 8000e1e: 3b b1                                cbz        r3, #14
  45. 8000e20: 04 32                                adds        r2, #4
  46. 8000e22: 91 07                                lsls        r1, r2, #30
  47. 8000e24: 07 d1                                bne        #14 <__loop+0x6a>
  48. 8000e26: 11 78                                ldrb        r1, [r2]
  49. 8000e28: 00 29                                cmp        r1, #0
  50. 8000e2a: ea d1                                bne        #-44 <__loop+0x36>
  51. 8000e2c: 10 1a                                subs        r0, r2, r0
  52. 8000e2e: 70 47                                bx        lr
  53. 8000e30: 0a 46                                mov        r2, r1
  54. 8000e32: 10 1a                                subs        r0, r2, r0
  55. 8000e34: 70 47                                bx        lr
  56. 8000e36: 11 46                                mov        r1, r2
  57. 8000e38: c5 e7                                b        #-118 <strlen+0x6>
复制代码

修正,编译器真就各种负优化...




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

1044

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3718
金钱
3718
注册时间
2011-5-23
在线时间
2012 小时
发表于 2020-2-15 17:30:20 | 显示全部楼层
RT-Thread RTOS 音频,WIFI,蓝牙
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
 楼主| 发表于 2020-2-15 17:30:49 | 显示全部楼层
aozima 发表于 2020-2-15 17:30
楼主研究得真深入

是新手
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
 楼主| 发表于 2020-2-15 18:53:42 | 显示全部楼层
本帖最后由 sppz 于 2020-2-15 21:28 编辑

反汇编看了下核心代码,效率应该非常高(usub8够快的话)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-8 06:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表