2010-09-09 3 views
5

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

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

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

Я имею в виду:

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) 
+2

255 + 255 = 510. – kennytm

ответ

11

Я порекомендую вам потратить немного времени на понимание того, как работает SIMD на ARM. Посмотрите:

Взгляните на:

  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-2-dealing-with-leftovers/
  3. http://blogs.arm.com/software-enablement/241-coding-for-neon-part-3-matrix-multiplication/
  4. http://blogs.arm.com/software-enablement/277-coding-for-neon-part-4-shifting-left-and-right/

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

3

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

На самом деле есть инструкция NEON, которая подходит для вашего алгоритма, называемого vaddw. Он добавит вектор dword к вектору qword, причем последний содержит элементы, которые в два раза шире первого. В вашем случае vaddw.u8 можно использовать для добавления 8 пикселов в 8 16-разрядных аккумуляторов. Затем vaddw.u16 можно использовать для добавления двух наборов из 8 16-разрядных аккумуляторов в один набор из 8 32-битных - обратите внимание, что вы должны использовать команду дважды, чтобы получить обе половины.

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

2

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

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

Вы можете использовать только регистр из 16 бит. это должно быть достаточно ...

0

Загрузите 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); 

 Смежные вопросы

  • Нет связанных вопросов^_^