Se non siete troppo interessati con precisione allora questo ciclo interno dovrebbe darvi il doppio del throughput di calcolo rispetto al algoritmo più preciso:
for (i=0; i<640; i+= 32)
{
uint8x16x2_t a, b;
uint8x16_t c, d;
/* load upper row, splitting even and odd pixels into a.val[0]
* and a.val[1] respectively. */
a = vld2q_u8(src1);
/* as above, but for lower row */
b = vld2q_u8(src2);
/* compute average of even and odd pixel pairs for upper row */
c = vrhaddq_u8(a.val[0], a.val[1]);
/* compute average of even and odd pixel pairs for lower row */
d = vrhaddq_u8(b.val[0], b.val[1]);
/* compute average of upper and lower rows, and store result */
vst1q_u8(dest, vrhaddq_u8(c, d));
src1+=32;
src2+=32;
dest+=16;
}
Funziona utilizzando l'operazione vhadd
, che ha un risultato della stessa dimensione dell'input. In questo modo non è necessario riportare la somma finale a 8 bit, e tutta l'aritmetica è di otto bit, il che significa che è possibile eseguire il doppio delle operazioni per istruzione.
Tuttavia è meno preciso, poiché la somma intermedia è quantizzata e GCC 4.7 fa un lavoro terribile di generazione del codice. GCC 4.8 funziona bene.
L'intera operazione ha buone probabilità di essere vincolata all'I/O. Il ciclo dovrebbe essere srotolato per massimizzare la separazione tra i carichi e l'aritmetica, e (o PLD
) dovrebbe essere usato per sollevare i dati in entrata in cache prima che sia necessario.
** Il migliore ** deve essere definito. Più veloce, alta qualità, dimensioni minime, ecc.? Per * la massima qualità *, ci sono diversi compromessi nella riduzione delle immagini. La conservazione del contenuto a bassa frequenza è importante in alcuni casi e ad alta frequenza in altri. Cosa è * 8-bit *? Una scala di grigi, mappata a colori o qualcos'altro? –
È un input di scala di grigi. Migliore = più veloce. – gregoiregentil