History

avutil/x86/aes: remove a few branches

The rounds value is constant and can be one of three hardcoded values, so instead of checking it on every loop, just split the function into three different implementations for each value. Before: aes_decrypt_128_aesni: 93.8 (47.58x) aes_decrypt_192_aesni: 106.9 (49.30x) aes_decrypt_256_aesni: 109.8 (56.50x) aes_encrypt_128_aesni: 93.2 (47.70x) aes_encrypt_192_aesni: 111.1 (48.36x) aes_encrypt_256_aesni: 113.6 (56.27x) After: aes_decrypt_128_aesni: 71.5 (63.31x) aes_decrypt_192_aesni: 96.8 (55.64x) aes_decrypt_256_aesni: 106.1 (58.51x) aes_encrypt_128_aesni: 81.3 (55.92x) aes_encrypt_192_aesni: 91.2 (59.78x) aes_encrypt_256_aesni: 109.0 (58.26x)

James Almer committed 1 year ago

Commit a0397261 parent 4d4b3013 files · +37 −22Browse files

Unified · Split

3 files
  1. libavutil/aes.c +1 −2
  2. libavutil/x86/aes.asm +16 −14
  3. libavutil/x86/aes_init.c +20 −6
libavutil/aes.c+1−2
@@ -234,6 +234,7 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) · 233 unmodified lines
234 int KC = key_bits >> 5;234 int KC = key_bits >> 5;
235 int rounds = KC + 6;235 int rounds = KC + 6;
236 236
237 a->rounds = rounds;
237 a->crypt = decrypt ? aes_decrypt : aes_encrypt;238 a->crypt = decrypt ? aes_decrypt : aes_encrypt;
238 if (ARCH_X86)239 if (ARCH_X86)
239 ff_init_aes_x86(a, decrypt);240 ff_init_aes_x86(a, decrypt);
@@ -243,8 +244,6 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) · 3 unmodified lines
243 if (key_bits != 128 && key_bits != 192 && key_bits != 256)244 if (key_bits != 128 && key_bits != 192 && key_bits != 256)
244 return AVERROR(EINVAL);245 return AVERROR(EINVAL);
245 246
246 a->rounds = rounds;
247
248 memcpy(tk, key, KC * 4);247 memcpy(tk, key, KC * 4);
249 memcpy(a->round_key[0].u8, key, KC * 4);248 memcpy(a->round_key[0].u8, key, KC * 4);
250 249
libavutil/x86/aes.asm+16−14
@@ -26,13 +26,12 @@ SECTION .text · 25 unmodified lines
26; void ff_aes_decrypt(AVAES *a, uint8_t *dst, const uint8_t *src,26; void ff_aes_decrypt(AVAES *a, uint8_t *dst, const uint8_t *src,
27; int count, uint8_t *iv, int rounds)27; int count, uint8_t *iv, int rounds)
28;-----------------------------------------------------------------------------28;-----------------------------------------------------------------------------
29%macro AES_CRYPT 129%macro AES_CRYPT 2
30cglobal aes_%1rypt, 6,6,230cglobal aes_%1rypt_%2, 5, 5, 2
31 test r3d, r3d31 test r3d, r3d
32 je .ret32 je .ret
33 shl r3d, 433 shl r3d, 4
34 add r5d, r5d34 add r0, 0x70
35 add r0, 0x60
36 add r2, r335 add r2, r3
37 add r1, r336 add r1, r3
38 neg r337 neg r3
@@ -45,17 +44,15 @@ cglobal aes_%1rypt, 6,6,2 · 6 unmodified lines
45%ifidn %1, enc44%ifidn %1, enc
46 pxor m0, m145 pxor m0, m1
47%endif46%endif
48 pxor m0, [r0+8*r5-0x60]47 pxor m0, [r0+8*2*%2-0x70]
49 cmp r5d, 2448%if %2 > 10
50 je .rounds1249%if %2 > 12
51 jl .rounds10
52 aes%1 m0, [r0+0x70]
53 aes%1 m0, [r0+0x60]50 aes%1 m0, [r0+0x60]
54.rounds12:
55 aes%1 m0, [r0+0x50]51 aes%1 m0, [r0+0x50]
52%endif
56 aes%1 m0, [r0+0x40]53 aes%1 m0, [r0+0x40]
57.rounds10:
58 aes%1 m0, [r0+0x30]54 aes%1 m0, [r0+0x30]
55%endif
59 aes%1 m0, [r0+0x20]56 aes%1 m0, [r0+0x20]
60 aes%1 m0, [r0+0x10]57 aes%1 m0, [r0+0x10]
61 aes%1 m0, [r0+0x00]58 aes%1 m0, [r0+0x00]
@@ -64,7 +61,8 @@ cglobal aes_%1rypt, 6,6,2 · 2 unmodified lines
64 aes%1 m0, [r0-0x30]61 aes%1 m0, [r0-0x30]
65 aes%1 m0, [r0-0x40]62 aes%1 m0, [r0-0x40]
66 aes%1 m0, [r0-0x50]63 aes%1 m0, [r0-0x50]
67 aes%1last m0, [r0-0x60]64 aes%1 m0, [r0-0x60]
65 aes%1last m0, [r0-0x70]
68 test r4, r466 test r4, r4
69 je .noiv67 je .noiv
70%ifidn %1, enc68%ifidn %1, enc
@@ -90,6 +88,10 @@ cglobal aes_%1rypt, 6,6,2 · 19 unmodified lines
90 88
91%if HAVE_AESNI_EXTERNAL89%if HAVE_AESNI_EXTERNAL
92INIT_XMM aesni90INIT_XMM aesni
93AES_CRYPT enc91AES_CRYPT enc, 10
94AES_CRYPT dec92AES_CRYPT enc, 12
93AES_CRYPT enc, 14
94AES_CRYPT dec, 10
95AES_CRYPT dec, 12
96AES_CRYPT dec, 14
95%endif97%endif
libavutil/x86/aes_init.c+20−6
@@ -22,15 +22,29 @@ · 21 unmodified lines
22#include "libavutil/aes_internal.h"22#include "libavutil/aes_internal.h"
23#include "libavutil/x86/cpu.h"23#include "libavutil/x86/cpu.h"
24 24
25void ff_aes_decrypt_aesni(AVAES *a, uint8_t *dst, const uint8_t *src,25void ff_aes_decrypt_10_aesni(AVAES *a, uint8_t *dst, const uint8_t *src,
26 int count, uint8_t *iv, int rounds);26 int count, uint8_t *iv, int rounds);
27void ff_aes_encrypt_aesni(AVAES *a, uint8_t *dst, const uint8_t *src,27void ff_aes_decrypt_12_aesni(AVAES *a, uint8_t *dst, const uint8_t *src,
28 int count, uint8_t *iv, int rounds);28 int count, uint8_t *iv, int rounds);
29void ff_aes_decrypt_14_aesni(AVAES *a, uint8_t *dst, const uint8_t *src,
30 int count, uint8_t *iv, int rounds);
31void ff_aes_encrypt_10_aesni(AVAES *a, uint8_t *dst, const uint8_t *src,
32 int count, uint8_t *iv, int rounds);
33void ff_aes_encrypt_12_aesni(AVAES *a, uint8_t *dst, const uint8_t *src,
34 int count, uint8_t *iv, int rounds);
35void ff_aes_encrypt_14_aesni(AVAES *a, uint8_t *dst, const uint8_t *src,
36 int count, uint8_t *iv, int rounds);
29 37
30void ff_init_aes_x86(AVAES *a, int decrypt)38void ff_init_aes_x86(AVAES *a, int decrypt)
31{39{
32 int cpu_flags = av_get_cpu_flags();40 int cpu_flags = av_get_cpu_flags();
33 41
34 if (EXTERNAL_AESNI(cpu_flags))42 if (EXTERNAL_AESNI(cpu_flags)) {
35 a->crypt = decrypt ? ff_aes_decrypt_aesni : ff_aes_encrypt_aesni;43 if (a->rounds == 10)
44 a->crypt = decrypt ? ff_aes_decrypt_10_aesni : ff_aes_encrypt_10_aesni;
45 else if (a->rounds == 12)
46 a->crypt = decrypt ? ff_aes_decrypt_12_aesni : ff_aes_encrypt_12_aesni;
47 else if (a->rounds == 14)
48 a->crypt = decrypt ? ff_aes_decrypt_14_aesni : ff_aes_encrypt_14_aesni;
49 }
36}50}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t