Суммируйте все элементы вектора четырехугольников в сборке ARM с помощью NEON - PullRequest
6 голосов
/ 03 августа 2011

Я довольно новичок в сборке, и хотя информационный центр по вооружению часто бывает полезен, иногда инструкции могут немного запутать новичка.По сути, мне нужно сложить 4 значения с плавающей запятой в регистре четырех слов и сохранить результат в регистре с одинарной точностью.Я думаю, что инструкция VPADD может делать то, что мне нужно, но я не совсем уверен.

Ответы [ 3 ]

4 голосов
/ 04 августа 2011

Вы можете попробовать это (это не в ASM, но вы должны быть в состоянии легко конвертировать):

float32x2_t r = vadd_f32(vget_high_f32(m_type), vget_low_f32(m_type));
return vget_lane_f32(vpadd_f32(r, r), 0);

В ASM это будут, вероятно, только VADD и VPADD.

Я не уверен, что это единственный способ сделать это (и самый оптимальный), но я не нашел / не нашел лучшего ...

PS. Я тоже новичок в NEON

2 голосов
/ 01 ноября 2011

Кажется, что вы хотите получить сумму определенной длины массива, а не только четыре значения с плавающей запятой.

В этом случае ваш код будет работать, но он далек от оптимизации:

  1. много-много конвейерных блокировок

  2. ненужное 32-битное сложение за итерацию

Предполагается, что длина массива равнакратное 8 и по меньшей мере 16:

  vldmia {q0-q1}, [pSrc]!
  sub count, count, #8
loop:
  pld [pSrc, #32]
  vldmia {q3-q4}, [pSrc]!
  subs count, count, #8
  vadd.f32 q0, q0, q3
  vadd.f32 q1, q1, q4
  bgt loop

  vadd.f32 q0, q0, q1
  vpadd.f32 d0, d0, d1
  vadd.f32 s0, s0, s1
  • pld - будучи инструкцией ARM, а не NEON - имеет решающее значение для производительности.Это резко увеличивает частоту обращений к кешу.

Надеюсь, остальная часть приведенного выше кода не требует пояснений.

Вы заметите, что эта версия во много раз быстрее, чем ваша первоначальная.

2 голосов
/ 05 августа 2011

Вот код в ASM:

    vpadd.f32 d1,d6,d7    @ q3 is register that needs all of its contents summed          
    vadd.f32 s1,s2,s3     @ now we add the contents of d1 together (the sum)                
    vadd.f32 s0,s0,s1     @ sum += s1;

Возможно, я забыл упомянуть, что в C код будет выглядеть так:этот маленький кусочек кода.

...