2013-07-30 21 views
8

Ho trovato un trucco da AGGREGATE Magic per valori massimi di elaborazione veloce. L'unico problema che questo è per i numeri interi, e tuttavia ho provato alcune cose, non ho idea di come fare una versione per interi senza segno.max senza diramazione per interi senza segno

inline int32_t max(int32_t a, int32_t b) 
{ 
    return a - ((a-b) & (a-b)>>31); 
} 

Qualche consiglio?

EDIT

non utilizzare questo, perché, come altri hanno dichiarato che produce un comportamento indefinito. Per qualsiasi architettura moderna il compilatore sarà in grado di emettere un'istruzione di movimento condizionale senza ramo da return (a > b) ? a : b, che sarà più veloce della funzione in questione.

+24

Aspetta, sei proprio sicuro che questo è più veloce di 'tornare a> b? a: b'? –

+10

Questa funzione è praticamente inutile. Usa 'std :: max'. –

+2

Sì, sulle moderne CPU con pipeline, i rami sono lenti. Ho misurato, questa versione tanto veloce quanto la versione SSE, se non più veloce. – plasmacel

risposta

9

Cosa fa questo codice? Prende il valore di ae la differenza a - b. Naturalmente, a - (a - b) è b. E (a - b) >> 31 crea semplicemente una maschera di quelli iff a - b è negativo.

Questo codice non è corretto, se si ottiene un overflow sulla sottrazione. Questo, tuttavia, è la stessa storia degli interi senza segno. Quindi, se e solo se siete soddisfatti con il fatto, che il codice non è corretto per l'intero intervallo di valori, si può semplicemente ignorare unsignedness e utilizza questa:

inline uint32_t umax(uint32_t a, uint32_t b) { 
    return (uint32_t)max((int32_t)a, (int32_t)b); 
} 
Problemi correlati