Любые инструкции NEON могут быть двойными, с кратным векторным накоплением (SMLAL) на Cortex A53 или A55? - PullRequest
1 голос
/ 30 января 2020

Я уже спрашивал на форумах разработчиков ARM, но ответов нет. https://community.arm.com/developer/tools-software/hpc/f/hpc-user-group/45524/any-neon-instructions-can-be-dual-issued-with-vector-long-multiply-accumulate-smlal-on-cortex-a53-or-a55

Кто-нибудь знает, возможно ли это? Я пробовал несколько комбинаций команд:

                                           A53                A55

smlal.int8 & 64bit load (ld1)              0.97               1.72                   instructions/cycle

smlal.int8 & 64bit dup                     0.97               0.96

smlal.int8 & 64bit or                      0.97               0.96

mla.int8 & 64bit dup                       1.79               1.74

mla.int16 & 64bit dup                      0.97               0.95

Руководство по оптимизации Cortex A55 содержит противоречивую информацию. https://static.docs.arm.com/epm128372/20/arm_cortex_a55_software_optimization_guide_v2.pdf

В одном месте говорится о двойной проблеме = 01, что в моем понимании означает, что он может выдавать только в слот 0, но позволяет другой инструкции SIMD выдавать в слоте 1.

Во 2-м месте говорится, что двойной выпуск = 00, что означает, что он предотвращает двойной выпуск , Означает ли это, что он использует оба слота?

Что еще удивительнее, даже то, что простое SIMD ИЛИ не может работать параллельно. Что я действительно хочу сделать, так это двойной выпуск dup (указать c lane) с smlal.

Что происходит? Использует ли smlal оба блока SIMD?

Одно предложение заключалось в том, что это может быть узким местом пропускной способности файла регистра

Могут ли Cortex-A57 выполнять 128-битные неоновые инструкции с двумя выпусками?

Это имеет смысл, потому что, в отличие от почти всех других инструкций, smlal берет 3 операнда и записывает вывод шириной в 2 раза, тогда как обычный mla выполняет только 3 чтения и 1 запись. И было бы очень неразумно добавлять третий порт записи в регистровый файл NEON для поддержки записи 128-битного вывода smlal и еще одного 64-битного вывода из 2-й инструкции

Другое объяснение состоит в том, что некоторые инструкции не могут быть выполнены дважды цикл (т. е. «векторная нагрузка не может быть выдана на 4-м цикле каждого кадра»)

https://github.com/Tencent/ncnn/wiki/arm-a53-a55-dual-issue

uint8_t data[32] __attribute__((aligned(32)));
for (int i = 0; i < N; i += 16)
{
  asm volatile(
  "smlal v9.8h, v0.8b, v0.8b\n"
  "ld1 {v0.8b},%0\n"
  "smlal v10.8h, v1.8b, v1.8b\n"
  "ld1 {v1.8b},%0\n"      
  "smlal v11.8h, v2.8b, v2.8b\n"
  "ld1 {v2.8b},%0\n"    
  "smlal v12.8h, v3.8b, v3.8b\n"
  "ld1 {v3.8b},%0\n" 
  "smlal v13.8h, v4.8b, v4.8b\n"
  "ld1 {v4.8b},%0\n"    
  "smlal v14.8h, v5.8b, v5.8b\n"
  "ld1 {v5.8b},%0\n"  
  "smlal v15.8h, v6.8b, v6.8b\n"
  "ld1 {v6.8b},%0\n"
  "smlal v0.8h, v7.8b, v7.8b\n"
  "ld1 {v7.8b},%0\n"
  "smlal v1.8h, v8.8b, v8.8b\n"
  "ld1 {v8.8b},%0\n"
  "smlal v2.8h, v9.8b, v9.8b\n"
  "ld1 {v9.8b},%0\n"
  "smlal v3.8h, v10.8b, v10.8b\n"
  "ld1 {v10.8b},%0\n"
  "smlal v4.8h, v11.8b, v11.8b\n"
  "ld1 {v11.8b},%0\n"
  "smlal v5.8h, v12.8b, v12.8b\n"
  "ld1 {v12.8b},%0\n"
  "smlal v6.8h, v13.8b, v13.8b\n"
  "ld1 {v13.8b},%0\n"
  "smlal v7.8h, v14.8b, v14.8b\n"
  "ld1 {v14.8b},%0\n"
  "smlal v8.8h, v15.8b, v15.8b\n"
  "ld1 {v15.8b},%0\n"
  : :"m"(data));

}
...