Domanda

il mio progetto di elaborazione delle immagini lavora con le immagini in scala di grigi. Ho piattaforma del processore ARM Cortex-A8. Voglio fare uso del NEON.

ho un immagine in scala di grigi (si consideri l'esempio qui sotto) e nel mio alogorithm, devo aggiungere solo le colonne.

Come caricare quattro valori a 8 bit pixel in parallelo, che sono uint8_t , come quattro uint32_t in uno dei 128 registri po NEON? Cosa intrinseca devo usare per fare questo?

I media:

alt text

devo caricarli come 32 bit, perché se si guarda con attenzione, il momento che faccio 255 + 255 è 512, che non può essere tenuto in un registro a 8 bit.

per es.

255 255 255 255 ......... (640 pixels)
255 255 255 255
255 255 255 255
255 255 255 255
.
.
.
.
.
(480 pixels) 
È stato utile?

Soluzione

I raccomanderà che si spende un po 'di comprensione tempo come funziona su ARM SIMD. Guardate:

Date un'occhiata a:

  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/

per iniziare. È quindi possibile implementare il codice SIMD utilizzando assembler in linea o corrispondente intrinseci ARM consigliati da Domen.

Altri suggerimenti

Dipende dalla vostra compilatore e (possibile mancanza di) estensioni.

Ie. per GCC, questo potrebbe essere un punto di partenza: http: //gcc.gnu .org / onlinedocs / gcc / ARM-Neon-Intrinsics.html

Se avete bisogno di sommare fino a 480 valori a 8 bit allora si sarebbe tecnicamente bisogno di 17 bit di stoccaggio intermedio. Tuttavia, se si esegue le aggiunte in due fasi, cioè, superiore 240 righe poi peggiori 240 righe, si può fare in 16-bit ciascuno. Quindi è possibile aggiungere i risultati dalle due metà per ottenere la risposta finale.

V'è in realtà un'istruzione NEON che è adatto per il vostro algoritmo chiamato vaddw. Si aggiunge un vettore DWORD un vettore QWORD, con gli elementi contenenti quest'ultimo due volte più ampia della prima. Nel tuo caso, vaddw.u8 può essere utilizzato per aggiungere 8 pixel a 8 accumulatori a 16 bit. Poi, vaddw.u16 può essere utilizzato per aggiungere le due serie di 8 accumulatori a 16 bit in un unico set di 8 quelli a 32 bit -. Si noti che è necessario utilizzare l'istruzione due volte per ottenere entrambe le metà

Se necessario, è possibile anche convertire i valori a 16-bit o 8 bit utilizzando vmovn o vqmovn.

Non è l'istruzione che può caricare il valore di 4 a 8 bit in 4 a 32 bit registro.

è necessario caricarle e quindi utilizzare un vshl due volte. perché neon non può utilizzare 32 registri dovrete lavorare su 8 pixel (e non 4)

È possibile utilizzare solo registrare 16 bit. dovrebbe essere abbastanza ...

Caricare i 4 byte utilizzando un'istruzione load singola corsia (vld1 <register>[<lane>], [<address]) in un q-registro, quindi utilizzare due istruzioni di movimento lungo (vmovl) promuovere loro prima 16 e poi a 32 bit. Il risultato dovrebbe essere qualcosa di simile (nella sintassi 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>)

Se si può garantire che <address> è di 4 byte allineati, quindi [<address>: 32] scrittura invece nelle istruzioni di carico, per salvare un ciclo o due. Se lo fai e l'indirizzo non è allineato, si otterrà un guasto, tuttavia.

Um, ho appena capito che si desidera utilizzare intrinseci, non di assemblaggio, quindi ecco la stessa cosa con intrinseche.

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top