Вопрос

Мой проект обработки изображений работает с изображениями в оттенках серого. У меня есть процессорная платформа ARM Cortex-A8. Я хочу использовать неон.

У меня есть изображение серого (рассмотрим пример ниже) и в моем алогоритеме, я должен добавить только столбцы.

Как я могу загрузить четыре 8-битных значения пикселей параллельно, которые uint8_t., так как четыре uint32_t. в один из 128-битных неоновых регистров? Какой внутренний я должен использовать для этого?

Я имею в виду:

alt text

Я должен загрузить их как 32 бита, потому что если вы посмотрите внимательно, в тот момент, когда я делаю 255 + 255, составляет 512, который не может быть проведен в 8-битном регистре.

например

255 255 255 255 ......... (640 pixels)
255 255 255 255
255 255 255 255
255 255 255 255
.
.
.
.
.
(480 pixels) 
Это было полезно?

Решение

Я порекомендую, чтобы вы проведете немного времени, понимая, как Simd работает на руке. Смотреть на:

Взгляни на:

  1. http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/
  2. http://blogs.arm.com/software-enablement/196-coding-for-neon-part-d-dealing-with-leftevers/
  3. http://blogs.arm.com/software-enablement/241-coding-for-neon-part-3-matrix-multipplication/
  4. http://blogs.arm.com/software-enablement/277-coding-for-neon-part-4-shifting-left-and-right/

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

Другие советы

Зависит от вашего компилятора и (возможному отсутствию) расширений.

Т.е. Для GCC это может быть отправной точкой: http://gcc.gnu.org/onlinedocs/gcc/arm-neon-intrinsics.html.

Если вам нужно суммировать до 480 8-битных значений, то вы будете технически нужны 17 бит промежуточного хранения. Однако, если вы выполняете дополнения в два этапа, т. Е. Топ 240 строк, затем нижние 240 строк, вы можете сделать это в 16-битах каждый. Затем вы можете добавить результаты с двух половинок, чтобы получить окончательный ответ.

На самом деле есть неоновая инструкция, которая подходит для вашего алгоритма, называемого VADDW. Он добавит вектор DWORD на вектор QWord, с последними содержащими элементами, которые в два раза шире, как у первого. В вашем случае VADDW.U8 можно использовать для добавления 8 пикселей до 8 16-битных аккумуляторов. Затем Vaddw.u16 можно использовать для добавления двух наборов из 8 16-битных аккумуляторов в один набор из 8 32-битных - обратите внимание, что вы должны использовать инструкцию дважды, чтобы получить обе половины.

При необходимости вы также можете преобразовать значения обратно в 16-битную или 8-битное, используя VMOVN или VQMOVN.

Там нет инструкции, которые могут загрузить ваше 4 8-битное значение на 4 32-битного реестра.

Вы должны загрузить их, а затем использовать VSHL дважды. Потому что неон не может использовать 32 регистров, которые вам придется работать на 8 пикселей (а не 4)

Вы можете использовать только 16bits Register. Это должно быть достаточно ...

Загрузить 4 байта с использованием однополосной нагрузки (vld1 <register>[<lane>], [<address]) в Q-реестр, затем используйте две инструкции по длине движения (vmovl) Продвигать их первым до 16, а затем до 32 бит. Результатом должно быть что-то вроде (в синтаксисе GNU)

vld1 d0[0], [<address>] @Now d0 = (*<addr>, *<addr+1>, *<addr+2>, *<addr+3>, <junk>, ... <junk> )
vmovl.u8 q0, d0 @Now q1 = (d0, d1) = ((uint16_t)*<addr>, ... (uint16_t)*<addr+3>, <junk>, ... <junk>)
vmovl.u16 q0, d2 @Now d0 = ((uint32_t)*<addr>, ... (uint32_t)*<addr+3>), d1 = (<junk>, ... <junk>)

Если вы можете гарантировать, что <address> 4-байт выровнен, то напиши [<address>: 32] Вместо этого в инструкции нагрузки, чтобы сохранить цикл или два. Если вы это сделаете, и адрес не выровнен, вы получите ошибку, однако.

Хм, я только что понял, что вы хотите использовать внутренние, а не в сборе, так что вот то же самое с внутренними лицами.

uint32x4_t v8; // Will actually hold 4 uint8_t
v8 = vld1_lane_u32(ptr, v8, 0);
const uint16x4_t v16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(v8)));
const uint32x4_t v32 = vmovl_u16(v16);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top