免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5041 | 回复: 16

汇编代码竟然没有 gcc -O2 快? (求更快的C/ASM算法) [复制链接]

论坛徽章:
0
发表于 2008-04-28 13:00 |显示全部楼层
需要一个简单快速的加密算法.
看过 DES, AES 后, 感觉在速度上难以符合要求.
就设计了一个简单的( 当然没有 DES, AES 安全性高 ):
以 8 个字节( 64 bit )为单位, 按密钥指定的顺序, 将每一个 bit 调整位置. 然后再和一个 64 bit 的异或码异或.
解密时按相反的顺序.

先写的 c 代码, 用了查表法.
后写的汇编代, 也用了查表法.
谁知道将 c 代码用 gcc -O2 优化后, 竟然比我的汇编代码还快.

我可真生气了.
用 gcc -S -O2 根据 .c 文件生成一个 .s 出来,
发现 .s 代码, 竟和我自己写的汇编代码惊人的一致.
仔细对比后, 参照 .s 将:
shr $1, %ebx
jnc \@.next
改为:
test $1<<\bit, %ebx
jz   \@.next
才总算扳平. 编解 100,000 个 1472 大小的包, c: 1.764646 秒, asm: 1.642376 秒, 占 0.x 秒的优势.

在 x86 (Intel(R) Pentium(R) 4 CPU 3.06GHz) 机器上, 一秒钟可以一编一解 82.5 MBytes 的数据.
但在 ARM 上每秒中才可以编解 10xx个包(大概 1.40MBytes), 太慢了.
想在 ARM 上用汇编优化, 不知道有多大的优化空间?
毕竟 gcc -O2 太厉害了, 在 pc 上用普通 x86 指令优化差别不大.
贴出代码, 求高人指点:

  1. typedef struct xbit_t xbit_t;
  2. struct xbit_t
  3. {
  4.     u32_t xor_low;      // 异或码( 0 ~ 31)
  5.     u32_t xor_high;     // 异或码(32 ~ 63)
  6.     u8_t  enc_move[64]; // 移位码(加密)
  7.     u8_t  dec_move[64]; // 移位码(解密)
  8. };

  9. #include <stdlib.h>
  10. #include <time.h>
  11. #include "def_type.h"
  12. #include "xbit.h"

  13. typedef struct sort_t sort_t;
  14. struct sort_t
  15. {
  16.     i32_t sort_key;
  17.     i32_t bit_move;
  18. };

  19. static i32_t compar( const void *a, const void *b )
  20. {
  21.     return ((sort_t *)a)->sort_key - ((sort_t *)b)->sort_key;
  22. }

  23. // 功能: 生成密钥
  24. // 参数: key : 指向存储密钥的结构
  25. void gen_key( xbit_t *key )
  26. {
  27.     i32_t   i;
  28.     u8_t   *p;
  29.     sort_t  arr[ ARR_E( key->enc_move ) ];

  30.     // 初始化随机数生成器
  31.     srandom( time(NULL) );

  32.     // 生成异或码
  33.     p = ( u8_t * )&key->xor_low;
  34.     for( i = 0; i < sizeof( key->xor_low ); i++ )
  35.     {
  36.         p[i] = random();
  37.     }
  38.     p = ( u8_t * )&key->xor_high;
  39.     for( i = 0; i < sizeof( key->xor_high ); i++ )
  40.     {
  41.         p[i] = random();
  42.     }

  43.     // 生成移位码
  44.     for( i = 0; i < ARR_E( arr ); i++ )
  45.     {
  46.         arr[i].sort_key = random();
  47.         arr[i].bit_move = i;
  48.     }
  49.     qsort( arr, ARR_E( arr ), sizeof( arr[0] ), compar );
  50.     for( i = 0; i < ARR_E( arr ); i++ )
  51.     {
  52.         key->enc_move[i] = arr[i].bit_move;
  53.         key->dec_move[arr[i].bit_move] = i;
  54.     }
  55. }
  56. #ifndef USE_ASM
  57. static const u32_t tab_low[] = \
  58. {
  59.     0x00000001, 0x00000002, 0x00000004, 0x00000008,
  60.     0x00000010, 0x00000020, 0x00000040, 0x00000080,
  61.     0x00000100, 0x00000200, 0x00000400, 0x00000800,
  62.     0x00001000, 0x00002000, 0x00004000, 0x00008000,
  63.     0x00010000, 0x00020000, 0x00040000, 0x00080000,
  64.     0x00100000, 0x00200000, 0x00400000, 0x00800000,
  65.     0x01000000, 0x02000000, 0x04000000, 0x08000000,
  66.     0x10000000, 0x20000000, 0x40000000, 0x80000000,
  67.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  68.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  69. };

  70. static const u32_t tab_high[] = \
  71. {
  72.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  73.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  74.     0x00000001, 0x00000002, 0x00000004, 0x00000008,
  75.     0x00000010, 0x00000020, 0x00000040, 0x00000080,
  76.     0x00000100, 0x00000200, 0x00000400, 0x00000800,
  77.     0x00001000, 0x00002000, 0x00004000, 0x00008000,
  78.     0x00010000, 0x00020000, 0x00040000, 0x00080000,
  79.     0x00100000, 0x00200000, 0x00400000, 0x00800000,
  80.     0x01000000, 0x02000000, 0x04000000, 0x08000000,
  81.     0x10000000, 0x20000000, 0x40000000, 0x80000000
  82. };

  83. // 功能: 加密并拷贝数据
  84. // 参数: key : 密钥
  85. //       dst : 加密后数据存放地
  86. //       src : 被加密数据来源地
  87. //       len : 数据长度( 字节数 )
  88. void xbit_enc( const xbit_t *key, void *dst, const void *src, u32_t len )
  89. {
  90.     const u8_t *bit_move;
  91.     u32_t       l, h, s, xor_low, xor_high;

  92.     xor_low  = key->xor_low;  // 取异或码( 0 ~ 31)
  93.     xor_high = key->xor_high; // 取异或码(32 ~ 63)
  94.     bit_move = key->enc_move; // 取移位码(加密)

  95.     len >>= 3;
  96.     while( len-- )
  97.     {
  98.         l = h = 0;
  99.         s = *( u32_t * )src;
  100.         src += 4;
  101.         if( s & 1 <<  0 ) { l |= tab_low[ bit_move[ 0] ]; h |= tab_high[ bit_move[ 0] ]; }
  102.         if( s & 1 <<  1 ) { l |= tab_low[ bit_move[ 1] ]; h |= tab_high[ bit_move[ 1] ]; }
  103.         if( s & 1 <<  2 ) { l |= tab_low[ bit_move[ 2] ]; h |= tab_high[ bit_move[ 2] ]; }
  104.         if( s & 1 <<  3 ) { l |= tab_low[ bit_move[ 3] ]; h |= tab_high[ bit_move[ 3] ]; }
  105.         if( s & 1 <<  4 ) { l |= tab_low[ bit_move[ 4] ]; h |= tab_high[ bit_move[ 4] ]; }
  106.         if( s & 1 <<  5 ) { l |= tab_low[ bit_move[ 5] ]; h |= tab_high[ bit_move[ 5] ]; }
  107.         if( s & 1 <<  6 ) { l |= tab_low[ bit_move[ 6] ]; h |= tab_high[ bit_move[ 6] ]; }
  108.         if( s & 1 <<  7 ) { l |= tab_low[ bit_move[ 7] ]; h |= tab_high[ bit_move[ 7] ]; }
  109.         if( s & 1 <<  8 ) { l |= tab_low[ bit_move[ 8] ]; h |= tab_high[ bit_move[ 8] ]; }
  110.         if( s & 1 <<  9 ) { l |= tab_low[ bit_move[ 9] ]; h |= tab_high[ bit_move[ 9] ]; }
  111.         if( s & 1 << 10 ) { l |= tab_low[ bit_move[10] ]; h |= tab_high[ bit_move[10] ]; }
  112.         if( s & 1 << 11 ) { l |= tab_low[ bit_move[11] ]; h |= tab_high[ bit_move[11] ]; }
  113.         if( s & 1 << 12 ) { l |= tab_low[ bit_move[12] ]; h |= tab_high[ bit_move[12] ]; }
  114.         if( s & 1 << 13 ) { l |= tab_low[ bit_move[13] ]; h |= tab_high[ bit_move[13] ]; }
  115.         if( s & 1 << 14 ) { l |= tab_low[ bit_move[14] ]; h |= tab_high[ bit_move[14] ]; }
  116.         if( s & 1 << 15 ) { l |= tab_low[ bit_move[15] ]; h |= tab_high[ bit_move[15] ]; }
  117.         if( s & 1 << 16 ) { l |= tab_low[ bit_move[16] ]; h |= tab_high[ bit_move[16] ]; }
  118.         if( s & 1 << 17 ) { l |= tab_low[ bit_move[17] ]; h |= tab_high[ bit_move[17] ]; }
  119.         if( s & 1 << 18 ) { l |= tab_low[ bit_move[18] ]; h |= tab_high[ bit_move[18] ]; }
  120.         if( s & 1 << 19 ) { l |= tab_low[ bit_move[19] ]; h |= tab_high[ bit_move[19] ]; }
  121.         if( s & 1 << 20 ) { l |= tab_low[ bit_move[20] ]; h |= tab_high[ bit_move[20] ]; }
  122.         if( s & 1 << 21 ) { l |= tab_low[ bit_move[21] ]; h |= tab_high[ bit_move[21] ]; }
  123.         if( s & 1 << 22 ) { l |= tab_low[ bit_move[22] ]; h |= tab_high[ bit_move[22] ]; }
  124.         if( s & 1 << 23 ) { l |= tab_low[ bit_move[23] ]; h |= tab_high[ bit_move[23] ]; }
  125.         if( s & 1 << 24 ) { l |= tab_low[ bit_move[24] ]; h |= tab_high[ bit_move[24] ]; }
  126.         if( s & 1 << 25 ) { l |= tab_low[ bit_move[25] ]; h |= tab_high[ bit_move[25] ]; }
  127.         if( s & 1 << 26 ) { l |= tab_low[ bit_move[26] ]; h |= tab_high[ bit_move[26] ]; }
  128.         if( s & 1 << 27 ) { l |= tab_low[ bit_move[27] ]; h |= tab_high[ bit_move[27] ]; }
  129.         if( s & 1 << 28 ) { l |= tab_low[ bit_move[28] ]; h |= tab_high[ bit_move[28] ]; }
  130.         if( s & 1 << 29 ) { l |= tab_low[ bit_move[29] ]; h |= tab_high[ bit_move[29] ]; }
  131.         if( s & 1 << 30 ) { l |= tab_low[ bit_move[30] ]; h |= tab_high[ bit_move[30] ]; }
  132.         if( s & 1 << 31 ) { l |= tab_low[ bit_move[31] ]; h |= tab_high[ bit_move[31] ]; }

  133.         s = *( u32_t * )src;
  134.         src += 4;
  135.         if( s & 1 <<  0 ) { l |= tab_low[ bit_move[32] ]; h |= tab_high[ bit_move[32] ]; }
  136.         if( s & 1 <<  1 ) { l |= tab_low[ bit_move[33] ]; h |= tab_high[ bit_move[33] ]; }
  137.         if( s & 1 <<  2 ) { l |= tab_low[ bit_move[34] ]; h |= tab_high[ bit_move[34] ]; }
  138.         if( s & 1 <<  3 ) { l |= tab_low[ bit_move[35] ]; h |= tab_high[ bit_move[35] ]; }
  139.         if( s & 1 <<  4 ) { l |= tab_low[ bit_move[36] ]; h |= tab_high[ bit_move[36] ]; }
  140.         if( s & 1 <<  5 ) { l |= tab_low[ bit_move[37] ]; h |= tab_high[ bit_move[37] ]; }
  141.         if( s & 1 <<  6 ) { l |= tab_low[ bit_move[38] ]; h |= tab_high[ bit_move[38] ]; }
  142.         if( s & 1 <<  7 ) { l |= tab_low[ bit_move[39] ]; h |= tab_high[ bit_move[39] ]; }
  143.         if( s & 1 <<  8 ) { l |= tab_low[ bit_move[40] ]; h |= tab_high[ bit_move[40] ]; }
  144.         if( s & 1 <<  9 ) { l |= tab_low[ bit_move[41] ]; h |= tab_high[ bit_move[41] ]; }
  145.         if( s & 1 << 10 ) { l |= tab_low[ bit_move[42] ]; h |= tab_high[ bit_move[42] ]; }
  146.         if( s & 1 << 11 ) { l |= tab_low[ bit_move[43] ]; h |= tab_high[ bit_move[43] ]; }
  147.         if( s & 1 << 12 ) { l |= tab_low[ bit_move[44] ]; h |= tab_high[ bit_move[44] ]; }
  148.         if( s & 1 << 13 ) { l |= tab_low[ bit_move[45] ]; h |= tab_high[ bit_move[45] ]; }
  149.         if( s & 1 << 14 ) { l |= tab_low[ bit_move[46] ]; h |= tab_high[ bit_move[46] ]; }
  150.         if( s & 1 << 15 ) { l |= tab_low[ bit_move[47] ]; h |= tab_high[ bit_move[47] ]; }
  151.         if( s & 1 << 16 ) { l |= tab_low[ bit_move[48] ]; h |= tab_high[ bit_move[48] ]; }
  152.         if( s & 1 << 17 ) { l |= tab_low[ bit_move[49] ]; h |= tab_high[ bit_move[49] ]; }
  153.         if( s & 1 << 18 ) { l |= tab_low[ bit_move[50] ]; h |= tab_high[ bit_move[50] ]; }
  154.         if( s & 1 << 19 ) { l |= tab_low[ bit_move[51] ]; h |= tab_high[ bit_move[51] ]; }
  155.         if( s & 1 << 20 ) { l |= tab_low[ bit_move[52] ]; h |= tab_high[ bit_move[52] ]; }
  156.         if( s & 1 << 21 ) { l |= tab_low[ bit_move[53] ]; h |= tab_high[ bit_move[53] ]; }
  157.         if( s & 1 << 22 ) { l |= tab_low[ bit_move[54] ]; h |= tab_high[ bit_move[54] ]; }
  158.         if( s & 1 << 23 ) { l |= tab_low[ bit_move[55] ]; h |= tab_high[ bit_move[55] ]; }
  159.         if( s & 1 << 24 ) { l |= tab_low[ bit_move[56] ]; h |= tab_high[ bit_move[56] ]; }
  160.         if( s & 1 << 25 ) { l |= tab_low[ bit_move[57] ]; h |= tab_high[ bit_move[57] ]; }
  161.         if( s & 1 << 26 ) { l |= tab_low[ bit_move[58] ]; h |= tab_high[ bit_move[58] ]; }
  162.         if( s & 1 << 27 ) { l |= tab_low[ bit_move[59] ]; h |= tab_high[ bit_move[59] ]; }
  163.         if( s & 1 << 28 ) { l |= tab_low[ bit_move[60] ]; h |= tab_high[ bit_move[60] ]; }
  164.         if( s & 1 << 29 ) { l |= tab_low[ bit_move[61] ]; h |= tab_high[ bit_move[61] ]; }
  165.         if( s & 1 << 30 ) { l |= tab_low[ bit_move[62] ]; h |= tab_high[ bit_move[62] ]; }
  166.         if( s & 1 << 31 ) { l |= tab_low[ bit_move[63] ]; h |= tab_high[ bit_move[63] ]; }
  167.         ( (u32_t *)dst )[0] = l ^ xor_low;
  168.         ( (u32_t *)dst )[1] = h ^ xor_high;
  169.         dst += 8;
  170.     }
  171. }

  172. // 功能: 解密并拷贝数据
  173. // 参数: key : 密钥
  174. //       dst : 解密后数据存放地
  175. //       src : 被解密数据来源地
  176. //       len : 数据长度( 字节数 )
  177. void xbit_dec( const xbit_t *key, void *dst, const void *src, u32_t len )
  178. {
  179.     // 略...
  180. }
  181. #endif

  182. // 汇编代码
  183.         .file   "xbit-x86.S"

  184. .macro MV32BIT bit, cnt = 0
  185. .if \cnt % 16 < 8
  186.         test    $1<<(\cnt%8), %bl
  187. .else
  188.         test    $1<<(\cnt%8), %bh
  189. .endif
  190.         jz      .\@next
  191.         movzbl  \bit(%ebp), %ecx
  192.         or      TAB(,%ecx,4), %eax
  193.         or      TAB+128(,%ecx,4), %edx
  194. .\@next:
  195. .ifeq \cnt - 15
  196.         shr     $16, %ebx
  197. .endif
  198. .if \cnt - 31
  199.         MV32BIT "(\bit+1)", "(\cnt+1)"
  200. .endif
  201. .endm

  202.         .text
  203.         .p2align 4,,15
  204. .globl  xbit_enc
  205.         .type   xbit_enc, @function
  206. xbit_enc:
  207.         push    %ebp
  208.         mov     %edi, -4(%esp)
  209.         mov     %esi, -8(%esp)
  210.         mov     %ebx, -12(%esp)

  211.         shrl    $3, 20(%esp)    # len /= 8
  212.         jz      .ENC_EXIT       # len > 0 ?

  213.         mov     8(%esp), %ebp   # ebp = key
  214.         mov     12(%esp), %edi  # edi = dst
  215.         mov     16(%esp), %esi  # esi = src
  216.         lea     8(%ebp), %ebp   # ebp = key->enc_move
  217.         .p2align 4,,7
  218. .ENC_LOOP:
  219.         xor     %eax, %eax      # l = 0
  220.         xor     %edx, %edx      # h = 0

  221.         mov     (%esi), %ebx    # ebx = src[0]
  222.         MV32BIT 0               # edx:eax <- ebx
  223.         mov     4(%esi), %ebx   # ebx = src[1]
  224.         MV32BIT 32              # edx:eax <- ebx

  225.         xor     -8(%ebp), %eax  # l ^= xor_low
  226.         xor     -4(%ebp), %edx  # h ^= xor_high

  227.         mov     %eax, (%edi)    # dst[0] = l
  228.         mov     %edx, 4(%edi)   # dst[1] = h

  229.         lea     8(%esi), %esi   # src += 8
  230.         lea     8(%edi), %edi   # dst += 8

  231.         decl    20(%esp)        # len -= 1
  232.         jnz     .ENC_LOOP       # len > 0 ?
  233.         .p2align 4,,7
  234. .ENC_EXIT:
  235.         mov     -4(%esp), %edi
  236.         mov     -8(%esp), %esi
  237.         mov     -12(%esp), %ebx
  238.         pop     %ebp
  239.         ret
  240.         .size   xbit_enc, .-xbit_enc

  241.         .p2align 4,,15
  242. .globl  xbit_dec
  243.         .type   xbit_dec, @function

  244.         // 略...

  245.         .size   xbit_dec, .-xbit_dec

  246.         .section .rodata
  247.         .align  32
  248.         .type   TAB, @object
  249.         .size   TAB, 384
  250. TAB:
  251.         .long   0x00000001, 0x00000002, 0x00000004, 0x00000008
  252.         .long   0x00000010, 0x00000020, 0x00000040, 0x00000080
  253.         .long   0x00000100, 0x00000200, 0x00000400, 0x00000800
  254.         .long   0x00001000, 0x00002000, 0x00004000, 0x00008000
  255.         .long   0x00010000, 0x00020000, 0x00040000, 0x00080000
  256.         .long   0x00100000, 0x00200000, 0x00400000, 0x00800000
  257.         .long   0x01000000, 0x02000000, 0x04000000, 0x08000000
  258.         .long   0x10000000, 0x20000000, 0x40000000, 0x80000000
  259.         .long   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  260.         .long   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  261.         .long   0x00000001, 0x00000002, 0x00000004, 0x00000008
  262.         .long   0x00000010, 0x00000020, 0x00000040, 0x00000080
  263.         .long   0x00000100, 0x00000200, 0x00000400, 0x00000800
  264.         .long   0x00001000, 0x00002000, 0x00004000, 0x00008000
  265.         .long   0x00010000, 0x00020000, 0x00040000, 0x00080000
  266.         .long   0x00100000, 0x00200000, 0x00400000, 0x00800000
  267.         .long   0x01000000, 0x02000000, 0x04000000, 0x08000000
  268.         .long   0x10000000, 0x20000000, 0x40000000, 0x80000000
  269.         .ident  "GCC: (GNU) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)"
  270.         .section    .note.GNU-stack,"",@progbits
复制代码

(附件有源码)

[ 本帖最后由 guoruimin 于 2008-4-30 08:44 编辑 ]

xbit.tar.gz

6.73 KB, 下载次数: 44

论坛徽章:
0
发表于 2008-04-28 13:12 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
发表于 2008-04-28 13:25 |显示全部楼层

回复 #2 torshie 的帖子

我深有同感,
我想让这一段代码在 ARM 上加速,
有什么好办法吗?
在 ARM 上有没有优化空间?
请指点?

论坛徽章:
36
2017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:2720周年集字徽章-周	
日期:2022-01-13 15:12:3320周年集字徽章-年
日期:2021-01-15 15:41:4420周年集字徽章-20	
日期:2020-10-28 14:04:30
发表于 2008-04-28 18:00 |显示全部楼层
老实用c吧, 一点也不值得这么做.

论坛徽章:
0
发表于 2008-04-28 18:04 |显示全部楼层
人肉优化,呵呵

论坛徽章:
0
发表于 2008-04-28 19:06 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
发表于 2008-04-28 22:05 |显示全部楼层

回复 #5 halve 的帖子

这段C代码在 ARM 上太慢,不能满足需求。
想请精通 ARM 的高人指点,这个算法能不能更快些。

论坛徽章:
0
发表于 2008-04-28 22:08 |显示全部楼层
你这是典型的非汇编思维写汇编程序
真想用汇编来写,先抛开C用纯汇编吧

[ 本帖最后由 mik 于 2008-4-28 22:09 编辑 ]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2008-04-28 22:16 |显示全部楼层
asm代替C,何必何必,看不懂了。
喝多酒了,钥匙丢了,罚面壁了..........

论坛徽章:
0
发表于 2008-04-28 22:20 |显示全部楼层
我对 ARM 汇编一点也不懂。
只是想请教高人,在 ARM 上有没有优化的空间。
这个简单的加密逻辑,
有没有更快的算法?
当然,能用 C 来实现一个比现在更快的更好。
那就真遇到高人了。期望中...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP