Wenn Sie mit Präzision nicht zu befürchten, dann ist diese innere Schleife sollten Sie zweimal geben den Rechendurchsatz im Vergleich zu den genaueren Algorithmus:
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;
}
Es funktioniert mit der vhadd
Operation, die ein Ergebnis die gleiche Größe wie der Eingang hat. Auf diese Weise müssen Sie die letzte Summe nicht wieder auf 8 Bit reduzieren, und die gesamte Arithmetik ist acht Bit lang, was bedeutet, dass Sie doppelt so viele Operationen pro Anweisung ausführen können.
Allerdings ist es weniger genau, weil die Zwischensumme quantisiert ist, und GCC 4.7 macht eine schreckliche Arbeit, Code zu erzeugen. GCC 4.8 geht gut.
Die gesamte Operation hat jedoch eine gute Chance, I/O gebunden zu sein. Die Schleife sollte entrollt werden, um die Trennung zwischen Lasten und Arithmetik zu maximieren, und __builtin_prefetch()
(oder PLD
) sollte verwendet werden, um die eingehenden Daten in Caches zu hieven, bevor sie benötigt werden. Hier
** Das Beste ** muss definiert werden. Schnellste, höchste Qualität, minimale Größe, etc? Für * höchste Qualität * gibt es unterschiedliche Kompromisse bei der Bildreduktion. Es ist wichtig, dass der Inhalt niedriger Frequenzen erhalten bleibt, in einigen Fällen und in anderen Fällen bei hohen Frequenzen. Was ist * 8-Bit *? Eine Graustufen-, Farbabbildung oder etwas anderes? –
Es ist ein Graustufen-Eingang. Am besten = am schnellsten. – gregoiregentil