Как ускорить шифрование по ГОСТ 28147-89 на процессоре Baikal-M

Наиболее важные замечания перед написанием алгоритма


В этом посте на примере описания реализации алгоритма шифрования по ГОСТ 28147–89, построенного на сети Фейстеля, показаны возможности процессора Baikal-M и проведен анализ конвейера и сравнительные испытания реализации алгоритма с помощью векторных вычислений с сопроцессором SIMD и без него.

Для тех, у кого нет времени или желания читать #многобукв# сразу результат — на Baikal-M можно получить 8×650Мбит/c ~ 5.2Гбит/с (с одного А57 ядра ~650Мбит/с)

СнК Baikal-M


Общая схема СнК ниже. Важно — СнК содержит 8 ядер ARM Cortex A57 (алгоритм оптимизирован под это ядро)

image

Ядро ARM Cortex-A57


Оптимизация алгоритма ГОСТ89 производится согласно документу ARM Cortex-A57 software optimization guide.
На следующем рисунке отображена схема конвейера ядер Cortex-A57 в составе процессора Baikal-M, для которого производилась оптимизация алгоритма.
image

Из документа ARM Cortex-A57 software optimization guide следует:

  1. Декодер принимает 3 инструкции за такт (пачка)
  2. Инструкция NOP может быть только 1 в пачке из 3
  3. Есть 2 исполняющих устройств ALU_INT по 64 бит (может быть направлено 2 микроинструкции типа add/or за такт)
  4. Есть 1 исполняющее устройство LOAD_MEM
  5. Есть 2 исполняющих устройств SIMD_INT по 128 бит (может быть направлено 2 микроинструкции типа vadd/vor за такт, но latency инструкций большое (больше 3 тактов))

Цель оптимизации — загрузить максимально декодер и все доступные вычислительные блоки в выполняемом алгоритме.

Алгоритм ГОСТ89


Про ГОСТ89 написано много, поэтому детально разбирать его в этом посте цели нет. Укажу только основные характеристики для понимания кода и оптимизации:
  1. Алгоритм построен на сети Фейстеля
  2. Состоит из 32 раундов
  3. Раунд состоит из подмешивания ключа и замены 8 частей по 4 бита по таблице со сдвигом на 11 бит.

Подробное описание алгоритмом преобразования информации по ГОСТ 28147–89 приведено собственно в Государственном Стандарте Союза ССР.

Оценка производительности предложенных реализаций алгоритма ГОСТ89

Шифрование 4 блоков на ALU_INT


Предложенный ниже алгоритм одного раунда использует ~54 инструкции. Декодер принимает три инструкции (см. п1) => предел декодера определяет минимальное время 18 тактов процессора.

Из этого рассчитываем максимальную теоретическую производительность на предложенном ниже алгоритме:
4×64 = 256 бит (такая пачка из 4 блоков по 64 бит)
256 / (18×32) ~ 0.444 (один раунд это 18 тактов процессора, всего 32 раунда)

Для Juno 1.1GHz
0.444×1100 ~ 488Мбит
На эксперименте получаем 447 Мбит

Для Байкал М-1000 1.5GHz
0.444×1500 ~ 660Мбит
На эксперименте получаем 600 Мбит

Предложенный код работает ~20 тактов на раунд т. е. нехватка исполнительных устройств и зависимость по регистрам в алгоритме съедают ~2 тактов декодера от предельного

Конфликт по данным в конце раунда даёт задержку один такт сразу и один такт когда требуется использовать регистр w22. т. е. конвейер не тормозится если конфликт внутри ALU т. е. процессор ведёт себя как superscalar out-of-order.

Остановка происходит, если есть конфликт по регистрам между исполнительными блоками (пример — конфликт ALU и LOAD_MEM) т. е. процессор ведёт себя как superscalar in-order. 

Wave формы


Разбираем подробнее где тормозит конвейер. Для этого смотрим загруженность декодера и клок. Нижняя последовательность это clk. Затем по три значения на входе декодера и как они меняются по ходу исполнения. Коды команд из листинга.

image

Code dump
// Prepare
4231dc: a9bf53f3 stp x19, x20, [sp, #-16]!
4231e0: a9bf5bf5 stp x21, x22, [sp, #-16]!
4231e4: a9bf63f7 stp x23, x24, [sp, #-16]!
4231e8: a9bf6bf9 stp x25, x26, [sp, #-16]!
4231ec: a9bf73fb stp x27, x28, [sp, #-16]!
4231f0: 29402408 ldp w8, w9, [x0]
4231f4: 29414c12 ldp w18, w19, [x0, #8]
4231f8: 29426c1a ldp w26, w27, [x0, #16]
4231fc: 29437007 ldp w7, w28, [x0, #24]
423200: b940004a ldr w10, [x2]
423204: 91100064 add x4, x3, #0×400
423208: 91200065 add x5, x3, #0×800
42320c: 91300066 add x6, x3, #0xc00

// Round 1
423210: 0b08014b add w11, w10, w8
423214: 0b120155 add w21, w10, w18
423218: d503201f nop

42321c: d3587d6c ubfx x12, x11, #24, #8
423220: d3505d6d ubfx x13, x11, #16, #8
423224: d503201f nop

423228: d3483d6e ubfx x14, x11, #8, #8
42322c: d3401d6f ubfx x15, x11, #0, #8
423230: b86c786c ldr w12, [x3, x12, lsl #2]

423234: d3587eb6 ubfx x22, x21, #24, #8
423238: d3505eb7 ubfx x23, x21, #16, #8
42323c: b86d788d ldr w13, [x4, x13, lsl #2]

423240: d3483eb8 ubfx x24, x21, #8, #8
423244: d3401eb9 ubfx x25, x21, #0, #8
423248: b86e78ae ldr w14, [x5, x14, lsl #2]

42324c: b86f78cf ldr w15, [x6, x15, lsl #2]
423250: 2a0d018c orr w12, w12, w13
423254: 0b1a014b add w11, w10, w26

423258: b8767876 ldr w22, [x3, x22, lsl #2]
42325c: 2a0f01ce orr w14, w14, w15
423260: 0b070155 add w21, w10, w7

423264: b8777897 ldr w23, [x4, x23, lsl #2]
423268: 2a0e018c orr w12, w12, w14
42326c: b87878b8 ldr w24, [x5, x24, lsl #2]

423270: 2a1702d6 orr w22, w22, w23
423274: 4a0c0129 eor w9, w9, w12
423278: b87978d9 ldr w25, [x6, x25, lsl #2]

42327c: d3587d6c ubfx x12, x11, #24, #8
423280: d3505d6d ubfx x13, x11, #16, #8
423284: 2a190318 orr w24, w24, w25

423288: d3483d6e ubfx x14, x11, #8, #8
42328c: b940044a ldr w10, [x2, #4]
423290: d3401d6f ubfx x15, x11, #0, #8

423294: 2a1802d6 orr w22, w22, w24
423298: b86c786c ldr w12, [x3, x12, lsl #2]
42329c: 4a160273 eor w19, w19, w22

4232a0: d3483eb8 ubfx x24, x21, #8, #8
4232a4: b86e78ae ldr w14, [x5, x14, lsl #2]
4232a8: d3587eb6 ubfx x22, x21, #24, #8

4232ac: d3505eb7 ubfx x23, x21, #16, #8
4232b0: b86d788d ldr w13, [x4, x13, lsl #2]
4232b4: d3401eb9 ubfx x25, x21, #0, #8

4232b8: 2a0d018c orr w12, w12, w13
4232bc: b86f78cf ldr w15, [x6, x15, lsl #2]
4232c0: b8767876 ldr w22, [x3, x22, lsl #2]

4232c4: 2a0f01ce orr w14, w14, w15
4232c8: b8777897 ldr w23, [x4, x23, lsl #2]
4232cc: 2a0e018c orr w12, w12, w14

4232d0: b87878b8 ldr w24, [x5, x24, lsl #2]
4232d4: 2a1702d6 orr w22, w22, w23
4232d8: 4a0c037b eor w27, w27, w12
// 2 ticks (LOAD_MEM + ALU, w25 conflict)
4232dc: b87978d9 ldr w25, [x6, x25, lsl #2]
4232e0: 2a190318 orr w24, w24, w25
4232e4: 2a1802d6 orr w22, w22, w24

4232e8: 4a16039c eor w28, w28, w22
// Round 2
4232ec: 0b09014b add w11, w10, w9
4232f0: 0b130155 add w21, w10, w19

4232f4: d503201f nop
4232f8: d3587d6c ubfx x12, x11, #24, #8
4232fc: d3505d6d ubfx x13, x11, #16, #8

423300: d503201f nop
423304: d3483d6e ubfx x14, x11, #8, #8
423308: d3401d6f ubfx x15, x11, #0, #8

42330c: b86c786c ldr w12, [x3, x12, lsl #2]
423310: d3587eb6 ubfx x22, x21, #24, #8
423314: d3505eb7 ubfx x23, x21, #16, #8
// 2 clks (w22 not ready, lack of ALU)
423318: b86d788d ldr w13, [x4, x13, lsl #2]
42331c: d3483eb8 ubfx x24, x21, #8, #8
423320: d3401eb9 ubfx x25, x21, #0, #8

423324: b86e78ae ldr w14, [x5, x14, lsl #2]
423328: b86f78cf ldr w15, [x6, x15, lsl #2]
42332c: 2a0d018c orr w12, w12, w13

423330: 0b1b014b add w11, w10, w27
423334: b8767876 ldr w22, [x3, x22, lsl #2]
423338: 2a0f01ce orr w14, w14, w15

42333c: 0b1c0155 add w21, w10, w28
423340: b8777897 ldr w23, [x4, x23, lsl #2]
423344: 2a0e018c orr w12, w12, w14

423348: b87878b8 ldr w24, [x5, x24, lsl #2]
42334c: 2a1702d6 orr w22, w22, w23
423350: 4a0c0108 eor w8, w8, w12

423354: b87978d9 ldr w25, [x6, x25, lsl #2]
423358: d3587d6c ubfx x12, x11, #24, #8
42335c: d3505d6d ubfx x13, x11, #16, #8

423360: 2a190318 orr w24, w24, w25
423364: d3483d6e ubfx x14, x11, #8, #8
423368: b940084a ldr w10, [x2, #8]

42336c: d3401d6f ubfx x15, x11, #0, #8
423370: 2a1802d6 orr w22, w22, w24
423374: b86c786c ldr w12, [x3, x12, lsl #2]
// 2 clk (lack of ALU)
423378: 4a160252 eor w18, w18, w22
42337c: d3483eb8 ubfx x24, x21, #8, #8
423380: b86e78ae ldr w14, [x5, x14, lsl #2]

423384: d3587eb6 ubfx x22, x21, #24, #8
423388: d3505eb7 ubfx x23, x21, #16, #8
42338c: b86d788d ldr w13, [x4, x13, lsl #2]

423390: d3401eb9 ubfx x25, x21, #0, #8
423394: 2a0d018c orr w12, w12, w13
423398: b86f78cf ldr w15, [x6, x15, lsl #2]

42339c: b8767876 ldr w22, [x3, x22, lsl #2]
4233a0: 2a0f01ce orr w14, w14, w15
4233a4: b8777897 ldr w23, [x4, x23, lsl #2]

4233a8: 2a0e018c orr w12, w12, w14
4233ac: b87878b8 ldr w24, [x5, x24, lsl #2]
4233b0: 2a1702d6 orr w22, w22, w23

4233b4: 4a0c035a eor w26, w26, w12
4233b8: b87978d9 ldr w25, [x6, x25, lsl #2]
4233bc: 2a190318 orr w24, w24, w25

4233c0: 2a1802d6 orr w22, w22, w24
4233c4: 4a1600e7 eor w7, w7, w22

Шифрование 10 блоков (6 блоков на ALU и 4 блока на NEON)

105 инструкций => предел декодера 105/3 = 35 тактов
10×64=640 бит (10 блоков по 64 бит)
640/(35×32) ~ 0.571 (32 раунда за 35 тактов)

Для Juno 1.1GHz
0.571×1100 ~ 628Мбит/с
На эксперименте получаем 494Мбит/с

Для Байкал М-1000 1.5GHz
0.571×1500 ~ 860Мбит
На эксперименте получаем 650 Мбит

Это ~44 тактов т. е. нехватка исполнительных устройств и зависимость по регистрам в алгоритме съедают ~9 тактов декодера

Большая latency на NEON даёт ~7 тактов задержки на замене по таблице (инструкции TBL). Сама инструкция не идёт в конвейер без подготовки, даже с учётом независимости по данным. Алгоритм пока не позволяет растянуть код для удаления зависимости. Ещё 2 такта добавляется на переходе между раундами.

Важно! Если возникает конфликт по данным NEON, то декодер тормозится полностью Пример — конфликт по регистру v3 из NEON останавливает и декодирование инструкций для обычного ALU т. е. в этом случае процессор superscalar in-order.

Wave формы


Разбираем подробнее, где тормозит конвейер. Для этого смотрим входы декодера на wave формах. Нижняя последовательность это clk. Затем по три значения на входе декодера и как они меняются по ходу исполнения. Коды команд из листинга.

image
image

Code dump
//Prepare
428500: a9bf4bf1 stp x17, x18, [sp, #-16]!
428504: a9bf53f3 stp x19, x20, [sp, #-16]!
428508: a9bf5bf5 stp x21, x22, [sp, #-16]!
42850c: a9bf63f7 stp x23, x24, [sp, #-16]!
428510: a9bf6bf9 stp x25, x26, [sp, #-16]!
428514: a9bf73fb stp x27, x28, [sp, #-16]!
428518: a9bf03f0 stp x16, x0, [sp, #-16]!
42851c: 28c12408 ldp w8, w9, [x0], #8
428520: 28c14c12 ldp w18, w19, [x0], #8
428524: 28c16c1a ldp w26, w27, [x0], #8
428528: 28c17007 ldp w7, w28, [x0], #8
42852c: 28c14410 ldp w16, w17, [x0], #8
428530: 28c11014 ldp w20, w4, [x0], #8
428534: b940004a ldr w10, [x2]
428538: 4c40a85e ld1 {v30.4s, v31.4s}, [x2]
42853c: 4e0407c0 dup v0.4s, v30.s[0]
428540: 4c408812 ld2 {v18.4s, v19.4s}, [x0]
428544: 2a0403e0 mov w0, w4

428548: 91100064 add x4, x3, #0×400
42854c: 91200065 add x5, x3, #0×800
428550: 91300066 add x6, x3, #0xc00
// Round 1
428554: 0b08014b add w11, w10, w8
// 3 clks (v0 SIMD)
428558: 0b120155 add w21, w10, w18
42855c: 4eb28401 add v1.4s, v0.4s, v18.4s
428560: d3587d6c ubfx x12, x11, #24, #8

428564: d3505d6d ubfx x13, x11, #16, #8
428568: 4e0c07c0 dup v0.4s, v30.s[1]
42856c: d3483d6e ubfx x14, x11, #8, #8

428570: d3401d6f ubfx x15, x11, #0, #8
428574: b86c786c ldr w12, [x3, x12, lsl #2]
428578: d3587eb6 ubfx x22, x21, #24, #8

42857c: b86d788d ldr w13, [x4, x13, lsl #2]
428580: 6f0c0423 ushr v3.16b, v1.16b, #4
428584: d3505eb7 ubfx x23, x21, #16, #8

428588: b86e78ae ldr w14, [x5, x14, lsl #2]
42858c: 4e311c25 and v5.16b, v1.16b, v17.16b
428590: d3483eb8 ubfx x24, x21, #8, #8

428594: b86f78cf ldr w15, [x6, x15, lsl #2]
428598: 4e301c24 and v4.16b, v1.16b, v16.16b
42859c: d3401eb9 ubfx x25, x21, #0, #8

4285a0: b8767876 ldr w22, [x3, x22, lsl #2]
4285a4: 4e311c66 and v6.16b, v3.16b, v17.16b
4285a8: 2a0d018c orr w12, w12, w13

4285ac: b8777897 ldr w23, [x4, x23, lsl #2]
4285b0: 4e301c67 and v7.16b, v3.16b, v16.16b
4285b4: 2a0f01ce orr w14, w14, w15

4285b8: b87878b8 ldr w24, [x5, x24, lsl #2]
4285bc: 4ea41cc4 orr v4.16b, v6.16b, v4.16b
4285c0: 2a0e018c orr w12, w12, w14

4285c4: 2a1702d6 orr w22, w22, w23
4285c8: 4ea71ca5 orr v5.16b, v5.16b, v7.16b
4285cc: 4a0c0129 eor w9, w9, w12

4285d0: 4ea41c87 mov v7.16b, v4.16b
4285d4: 4ea51ca6 mov v6.16b, v5.16b
4285d8: 0b1a014b add w11, w10, w26

4285dc: b87978d9 ldr w25, [x6, x25, lsl #2]
4285e0: 4e040104 tbl v4.16b, {v8.16b}, v4.16b
4285e4: 0b070155 add w21, w10, w7

4285e8: 2a190318 orr w24, w24, w25
4285ec: 4e050125 tbl v5.16b, {v9.16b}, v5.16b
4285f0: 2a1802d6 orr w22, w22, w24
// 4 clks (TBL q-form 3×1+3 = 6 latency!)
4285f4: d503201f nop
4285f8: 4e060146 tbl v6.16b, {v10.16b}, v6.16b
4285fc: 4a160273 eor w19, w19, w22
428600: d3587d6c ubfx x12, x11, #24, #8
// 2 clks
428604: 4e070167 tbl v7.16b, {v11.16b}, v7.16b
428608: d3505d6d ubfx x13, x11, #16, #8
42860c: b86c786c ldr w12, [x3, x12, lsl #2]
// 3 clks
428610: 4e2c1c84 and v4.16b, v4.16b, v12.16b
428614: d3483d6e ubfx x14, x11, #8, #8
428618: d3401d6f ubfx x15, x11, #0, #8
// 3 clk
42861c: 4e2d1ca5 and v5.16b, v5.16b, v13.16b
428620: d3587eb6 ubfx x22, x21, #24, #8
428624: b86d788d ldr w13, [x4, x13, lsl #2]

428628: 4e2e1cc6 and v6.16b, v6.16b, v14.16b
42862c: d3505eb7 ubfx x23, x21, #16, #8
428630: b86e78ae ldr w14, [x5, x14, lsl #2]

428634: 4e2f1ce7 and v7.16b, v7.16b, v15.16b
428638: d3483eb8 ubfx x24, x21, #8, #8
42863c: b86f78cf ldr w15, [x6, x15, lsl #2]

428640: 4ea51c84 orr v4.16b, v4.16b, v5.16b
428644: d3401eb9 ubfx x25, x21, #0, #8
428648: b8767876 ldr w22, [x3, x22, lsl #2]

42864c: 4ea71cc6 orr v6.16b, v6.16b, v7.16b
428650: 2a0d018c orr w12, w12, w13
428654: b8777897 ldr w23, [x4, x23, lsl #2]
// 2 clks
428658: 4ea61c84 orr v4.16b, v4.16b, v6.16b
42865c: 2a0f01ce orr w14, w14, w15
428660: b87878b8 ldr w24, [x5, x24, lsl #2]

428664: 6f2b0481 ushr v1.4s, v4.4s, #21
428668: 2a0e018c orr w12, w12, w14
42866c: b87978d9 ldr w25, [x6, x25, lsl #2]

428670: 4f2b5483 shl v3.4s, v4.4s, #11
428674: 2a1702d6 orr w22, w22, w23
428678: 0b10014b add w11, w10, w16
// 2 clks
42867c: 4ea31c35 orr v21.16b, v1.16b, v3.16b
428680: 2a190318 orr w24, w24, w25
428684: 4a0c037b eor w27, w27, w12

428688: d503201f nop
42868c: 2a1802d6 orr w22, w22, w24
428690: 0b140155 add w21, w10, w20

428694: 4a16039c eor w28, w28, w22
428698: d3587d6c ubfx x12, x11, #24, #8
42869c: 6e351e73 eor v19.16b, v19.16b, v21.16b
// 2clks
4286a0: d3505d6d ubfx x13, x11, #16, #8
4286a4: b940044a ldr w10, [x2, #4]
4286a8: d3483d6e ubfx x14, x11, #8, #8

4286ac: d3401d6f ubfx x15, x11, #0, #8
4286b0: b86c786c ldr w12, [x3, x12, lsl #2]
4286b4: d3587eb6 ubfx x22, x21, #24, #8

4286b8: d3505eb7 ubfx x23, x21, #16, #8
4286bc: b86d788d ldr w13, [x4, x13, lsl #2]
4286c0: d3483eb8 ubfx x24, x21, #8, #8

4286c4: d3401eb9 ubfx x25, x21, #0, #8
4286c8: b86e78ae ldr w14, [x5, x14, lsl #2]
4286cc: b86f78cf ldr w15, [x6, x15, lsl #2]
// 2clks
4286d0: 2a0d018c orr w12, w12, w13
4286d4: d503201f nop
4286d8: b8767876 ldr w22, [x3, x22, lsl #2]

4286dc: 2a0f01ce orr w14, w14, w15
4286e0: b8777897 ldr w23, [x4, x23, lsl #2]
4286e4: 2a0e018c orr w12, w12, w14

4286e8: b87878b8 ldr w24, [x5, x24, lsl #2]
4286ec: 2a1702d6 orr w22, w22, w23
4286f0: 4a0c0231 eor w17, w17, w12

// 2 clks
4286f4: b87978d9 ldr w25, [x6, x25, lsl #2]
4286f8: 2a190318 orr w24, w24, w25
4286fc: 2a1802d6 orr w22, w22, w24

428700: 4a160000 eor w0, w0, w22
// Round 2
428704: 0b09014b add w11, w10, w9
428708: 0b130155 add w21, w10, w19

42870c: 4eb38401 add v1.4s, v0.4s, v19.4s
428710: d3587d6c ubfx x12, x11, #24, #8
428714: d3505d6d ubfx x13, x11, #16, #8

428718: 4e1407c0 dup v0.4s, v30.s[2]
42871c: d3483d6e ubfx x14, x11, #8, #8
428720: d3401d6f ubfx x15, x11, #0, #8

428724: b86c786c ldr w12, [x3, x12, lsl #2]
428728: d3587eb6 ubfx x22, x21, #24, #8
42872c: b86d788d ldr w13, [x4, x13, lsl #2]

428730: 6f0c0423 ushr v3.16b, v1.16b, #4
428734: d3505eb7 ubfx x23, x21, #16, #8
428738: b86e78ae ldr w14, [x5, x14, lsl #2]

42873c: 4e311c25 and v5.16b, v1.16b, v17.16b
428740: d3483eb8 ubfx x24, x21, #8, #8
428744: b86f78cf ldr w15, [x6, x15, lsl #2]

428748: 4e301c24 and v4.16b, v1.16b, v16.16b
42874c: d3401eb9 ubfx x25, x21, #0, #8
428750: b8767876 ldr w22, [x3, x22, lsl #2]

428754: 4e311c66 and v6.16b, v3.16b, v17.16b
428758: 2a0d018c orr w12, w12, w13
42875c: b8777897 ldr w23, [x4, x23, lsl #2]

428760: 4e301c67 and v7.16b, v3.16b, v16.16b
428764: 2a0f01ce orr w14, w14, w15
428768: b87878b8 ldr w24, [x5, x24, lsl #2]

42876c: 4ea41cc4 orr v4.16b, v6.16b, v4.16b
428770: 2a0e018c orr w12, w12, w14
428774: 2a1702d6 orr w22, w22, w23

428778: 4ea71ca5 orr v5.16b, v5.16b, v7.16b
42877c: 4a0c0108 eor w8, w8, w12
428780: 4ea41c87 mov v7.16b, v4.16b

428784: 4ea51ca6 mov v6.16b, v5.16b
428788: 0b1b014b add w11, w10, w27
42878c: b87978d9 ldr w25, [x6, x25, lsl #2]

428790: 4e040104 tbl v4.16b, {v8.16b}, v4.16b
428794: 0b1c0155 add w21, w10, w28
428798: 2a190318 orr w24, w24, w25

42879c: 4e050125 tbl v5.16b, {v9.16b}, v5.16b
4287a0: 2a1802d6 orr w22, w22, w24
4287a4: d503201f nop
// 3clks (TBL q-form 3×1+3 = 6 latency!)
4287a8: 4e060146 tbl v6.16b, {v10.16b}, v6.16b
4287ac: 4a160252 eor w18, w18, w22
4287b0: d3587d6c ubfx x12, x11, #24, #8
// 2clk
4287b4: 4e070167 tbl v7.16b, {v11.16b}, v7.16b
4287b8: d3505d6d ubfx x13, x11, #16, #8
4287bc: b86c786c ldr w12, [x3, x12, lsl #2]
// 4 clks
4287c0: 4e2c1c84 and v4.16b, v4.16b, v12.16b
4287c4: d3483d6e ubfx x14, x11, #8, #8
4287c8: d3401d6f ubfx x15, x11, #0, #8
// 2 clks
4287cc: 4e2d1ca5 and v5.16b, v5.16b, v13.16b
4287d0: d3587eb6 ubfx x22, x21, #24, #8
4287d4: b86d788d ldr w13, [x4, x13, lsl #2]

4287d8: 4e2e1cc6 and v6.16b, v6.16b, v14.16b
4287dc: d3505eb7 ubfx x23, x21, #16, #8
4287e0: b86e78ae ldr w14, [x5, x14, lsl #2]

4287e4: 4e2f1ce7 and v7.16b, v7.16b, v15.16b
4287e8: d3483eb8 ubfx x24, x21, #8, #8
4287ec: b86f78cf ldr w15, [x6, x15, lsl #2]

4287f0: 4ea51c84 orr v4.16b, v4.16b, v5.16b
4287f4: d3401eb9 ubfx x25, x21, #0, #8
4287f8: b8767876 ldr w22, [x3, x22, lsl #2]

4287fc: 4ea71cc6 orr v6.16b, v6.16b, v7.16b
428800: 2a0d018c orr w12, w12, w13
428804: b8777897 ldr w23, [x4, x23, lsl #2]
// 2 clks
428808: 4ea61c84 orr v4.16b, v4.16b, v6.16b
42880c: 2a0f01ce orr w14, w14, w15
428810: b87878b8 ldr w24, [x5, x24, lsl #2]

428814: 6f2b0481 ushr v1.4s, v4.4s, #21
428818: 2a0e018c orr w12, w12, w14
42881c: b87978d9 ldr w25, [x6, x25, lsl #2]

428820: 4f2b5483 shl v3.4s, v4.4s, #11
428824: 2a1702d6 orr w22, w22, w23
428828: 0b11014b add w11, w10, w17

42882c: 4ea31c35 orr v21.16b, v1.16b, v3.16b
428830: 2a190318 orr w24, w24, w25
428834: 4a0c035a eor w26, w26, w12
// 2 clks
428838: d503201f nop
42883c: 2a1802d6 orr w22, w22, w24
428840: 0b000155 add w21, w10, w0

428844: 4a1600e7 eor w7, w7, w22
428848: d3587d6c ubfx x12, x11, #24, #8
42884c: 6e351e52 eor v18.16b, v18.16b, v21.16b

428850: d3505d6d ubfx x13, x11, #16, #8
428854: b940084a ldr w10, [x2, #8]
428858: d3483d6e ubfx x14, x11, #8, #8

42885c: d3401d6f ubfx x15, x11, #0, #8
428860: b86c786c ldr w12, [x3, x12, lsl #2]
428864: d3587eb6 ubfx x22, x21, #24, #8

428868: d3505eb7 ubfx x23, x21, #16, #8
42886c: b86d788d ldr w13, [x4, x13, lsl #2]
428870: d3483eb8 ubfx x24, x21, #8, #8

428874: d3401eb9 ubfx x25, x21, #0, #8
428878: b86e78ae ldr w14, [x5, x14, lsl #2]
42887c: b86f78cf ldr w15, [x6, x15, lsl #2]

428880: 2a0d018c orr w12, w12, w13
428884: d503201f nop
428888: b8767876 ldr w22, [x3, x22, lsl #2]

42888c: 2a0f01ce orr w14, w14, w15
428890: b8777897 ldr w23, [x4, x23, lsl #2]
428894: 2a0e018c orr w12, w12, w14

428898: b87878b8 ldr w24, [x5, x24, lsl #2]
42889c: 2a1702d6 orr w22, w22, w23
4288a0: 4a0c0210 eor w16, w16, w12

4288a4: b87978d9 ldr w25, [x6, x25, lsl #2]
4288a8: 2a190318 orr w24, w24, w25
4288ac: 2a1802d6 orr w22, w22, w24

4288b0: 4a160294 eor w20, w20, w22
4288b4: 0b08014b add w11, w10, w8

Выводы


На Baikal-M можно получить скорость 8×650Мбит/c ~ 5.2Гбит/с в алгоритме ГОСТ89 или магма (с одного ядра Cortex-А57 ~650Мбит/с).
Ядра ARM описаны хорошо, но имеют достаточно сложное устройство конвейера. В посте предложен пример оптимизации кода.
Этот пример должен работать до ядер А75. Более новые ARM ядра имеют улучшенный конвейер.

Где можно почитать подробнее об оптимизации, если интересно:


Cortex-A57 Software Optimization Guide https://developer.arm.com/documentation/uan0015/b/
Arm Architecture Reference Manual Armv8 https://developer.arm.com/documentation/ddi0487/latest/

© Habrahabr.ru