Sommario:
Sto cercando il modo più veloce per calcolare
(int) x / (int) y
senza ottenere un'eccezione per y==0
. Invece voglio solo un risultato arbitrario.
Sfondo:
Quando si codificano algoritmi di elaborazione delle immagini, spesso è necessario dividere per un valore alfa (accumulato). La variante più semplice è il semplice codice C con aritmetica dei numeri interi. Il mio problema è che in genere ottengo una divisione per errore zero per i pixel dei risultati con alpha==0
. Tuttavia questi sono esattamente i pixel in cui il risultato non ha alcuna importanza: non mi interessano i valori di colore dei pixel con alpha==0
.
Dettagli:
Sto cercando qualcosa come:
result = (y==0)? 0 : x/y;
o
result = x / MAX( y, 1 );
xey sono numeri interi positivi. Il codice viene eseguito un numero enorme di volte in un ciclo annidato, quindi sto cercando un modo per sbarazzarmi della ramificazione condizionale.
Quando y non supera l'intervallo di byte, sono soddisfatto della soluzione
unsigned char kill_zero_table[256] = { 1, 1, 2, 3, 4, 5, 6, 7, [...] 255 };
[...]
result = x / kill_zero_table[y];
Ma questo ovviamente non funziona bene per gamme più grandi.
Immagino che la domanda finale sia: qual è il trucco più veloce che cambia 0 in qualsiasi altro valore intero, lasciando tutti gli altri valori invariati?
chiarimenti
Non sono sicuro al 100% che la ramificazione sia troppo costosa. Tuttavia, vengono utilizzati compilatori diversi, quindi preferisco il benchmarking con poche ottimizzazioni (il che è davvero discutibile).
Di sicuro, i compilatori sono fantastici quando si tratta di manipolare un po ', ma non posso esprimere il risultato "non mi interessa" in C, quindi il compilatore non sarà mai in grado di utilizzare l'intera gamma di ottimizzazioni.
Il codice dovrebbe essere completamente compatibile con C, le piattaforme principali sono Linux 64 Bit con gcc & clang e MacOS.
y += !y
? Nessun ramo necessario per calcolarlo. Potresti confrontare x / (y + !y)
con x / max(y, 1)
e forse anche y ? (x/y) : 0
. Immagino che non ci saranno rami in nessuno di essi, almeno con le ottimizzazioni attivate.
0
sezioni alfa sono enormi e contigue. C'è un posto per giocherellare con le micro ottimizzazioni e le operazioni per pixel sono esattamente quelle.