Il mio programma è conforme alla regola di aliasing rigorosa, ad eccezione di un posto: un'unità di compilazione che contiene funzioni di hashing come MurmurHash3, SpookyHash, ecc. Su x86 e x86_64, queste funzioni di hashing accettano uno const char *
, li inoltrano a uint32
e processano dati in blocchi di 4 byte. Questo li rende molto più veloci rispetto ai dati di elaborazione byte per byte, ma credo che ciò infrange la rigida regola dell'aliasing. In questo momento, compilo questa compilation con -fno-strict-aliasing, mentre compilo il resto del programma con -fstrict-aliasing.È possibile abilitare l'ottimizzazione link-time mentre si disabilita solo l'aliasing rigoroso per alcune funzioni?
Ma mi chiedo cosa succede se abilito l'ottimizzazione link-time. Per quanto ne so, GCC e Clang implementano l'ordinamento di ottimizzazione del link-time memorizzando la sorgente del programma in file .o, in modo che nella fase di collegamento il compilatore conosca il codice sorgente dell'intero programma. È quindi ancora possibile disabilitare il rigoroso aliasing solo per le funzioni di hashing? O ora devo disabilitare il rigoroso aliasing per l'intero programma? O ho frainteso completamente le cose, e MurmurHash3/SpookyHash sono in effetti rigorosi aliasing conformi?
Perché non si può semplicemente utilizzare 'memcpy' per copiare i byte in una variabile locale di tipo' uint32', e quindi operare su quella variabile locale? Questo dovrebbe essere ottimizzato per l'equivalente del tuo codice, ma senza violare alcuna regola di aliasing. – hvd
Non ero sicuro se il compilatore sarebbe stato in grado di ottimizzare questo. Se lo fa, sarebbe fantastico. Ma vedendo la risposta di Christoph, sembrerebbe che il compilatore non sia in grado di ottimizzarlo. – Hongli
La risposta di Christoph contiene un collegamento al codice e quel codice non fa ciò che ho descritto. Quando si vogliono trattare i buffer di varie dimensioni come serie di valori 'uint64_t', quel codice copia l'intero buffer in una matrice di' uint64_t' (come parte di 'union'), e quello che sto descrivendo è avere un singolo 'uint64_t' variabile e copia ripetutamente gli 8 byte specifici che vuoi leggere. – hvd