Встроенная инструкция по сборке Raspberry Pi 2 NEON не работает

Я пытался заставить свой старый код работать быстрее, поскольку обнаружил, что процессор RPi 2 поддерживает инструкции NEON. Итак, я написал этот код:

__asm__ __volatile__(
  "vld1.8 {%%d2, %%d3}, [%1];"
  "vld1.8 {%%d4, %%d5}, [%2];"
  "vaba.u8 %%q0, %%q1, %%q2;"
  "vst1.64 %%d0, [%0];"
  : "=r" (address_sad_intermediary)
  : "r" (address_big_pic), "r" (address_small_pic)
  :
);

Затем в C основная переменная sad суммируется с sad_intermediary.

Основная цель - вычислить сумму абсолютных разностей, поэтому я загружаю 16 B из big_pic в регистр q1, 16 B из small_pic в регистр q2, вычисляю SAD в q0, а затем загружаю меньшие 8 B из q0 в промежуточную переменную. Проблема в том, что в результате печальный результат равен нулю.

Я использую GCC 4.9.2 с -std = c99 -pthread -O3 -lm -Wall -march = armv7-a -mfpu = neon-vfpv4 -mfloat-abi = hard варианты.

Вы видите проблемы с кодом? Спасибо.


person Fehér Zoltán    schedule 30.04.2016    source источник


Ответы (1)


Вы никогда ничего не загружаете в q0, поэтому vaba добавляет абсолютную разницу в неинициализированный регистр. Также похоже, что вы не объявляете, какие регистры изменяете.

Но я не знаю, является ли это причиной вашей проблемы, потому что я не очень удобен со встроенной сборкой. Однако вам, вероятно, не следует использовать встроенную сборку для чего-то вроде этого. Если вы используете встроенные функции, то компилятор имеет больше возможностей для оптимизации кода. Что-то вроде этого:

#include <arm_neon.h>

...
uint8x8_t s = vld1_u8(address_sad_intermediary);
s = vaba_u8(s, vld1_u8(address_big_pic), vld1_u8(address_small_pic));
vst1_u8(address_sad_intermediary, s);

(обратите внимание, что этот код работает только с восемью байтами, потому что вы сохраняете только восемь байтов в своем коде)

person sh1    schedule 01.05.2016
comment
Но почему я в q0 ничего не загружаю? В этом документе p58 вы можете видеть, что результат сохраняется в первый регистр, в моем случае q0. Я не хотел использовать встроенные функции, потому что читал, что производительность у них не идеальная. - person Fehér Zoltán; 01.05.2016
comment
При встроенной сборке производительность может быть хуже. Производительность встроенных функций исторически была ужасной, но теперь доступен gcc-6.1, и это, как и современный Clang, неплохо справляется со своей задачей. Пока код прост, они не должны ошибаться, и они будут обрабатывать планирование конвейера без необходимости думать об этом. - person sh1; 01.05.2016
comment
vaba читает из q0 и добавляет к этому абсолютную разницу между q1 и q2. У вас должно быть что-то в q0, прежде чем вы сможете выполнить операцию, иначе вы получите бессмысленный результат. - person sh1; 01.05.2016
comment
Я попробовал встроенные функции и, посмотрев на сгенерированный код ASM, который выглядел нормально, я пошел по этому пути. Основная проблема заключалась в том, что я не понимал, что векторная переменная генерации vaba не является скаляром. - person Fehér Zoltán; 02.05.2016