Heim >Backend-Entwicklung >C++ >Warum unterbricht die Compiler-Optimierung diese 64-Bit-Swap-Funktion?
Warum Optimierung diese Funktion beeinträchtigt
In einer Universitätsvorlesung über Programmierspezialitäten stellte ein Dozent eine Funktion vor, die Studenten verblüffte:
inline u64 Swap_64(u64 x) { u64 tmp; (*(u32*)&tmp) = Swap_32(*(((u32*)&x)+1)); (*(((u32*)&tmp)+1)) = Swap_32(*(u32*) &x); return tmp; }
Anfangs funktionierte die Funktion reibungslos, aber nach der Aktivierung hoher Optimierungsstufen wurde sie inaktiv. Der Grund für dieses Verhalten liegt im Konzept der strengen Aliasing-Regeln.
Strenge Aliasing-Verletzung
Der bereitgestellte Code verstößt gegen strenge Aliasing-Regeln, die vorschreiben, dass nur Objekte zulässig sind Der Zugriff erfolgt über kompatible Zeigertypen. In diesem Fall verweisen die u32- und u64-Zeiger auf möglicherweise überlappenden Speicher, der Compiler geht jedoch davon aus, dass sie unterschiedliche Objekte darstellen. Diese Annahme ermöglicht es ihm, Zuweisungen an die temporäre Variable tmp zu optimieren, wodurch die Funktion unwirksam wird.
Warum die Optimierung stattfindet
Der Compiler darf Code basierend auf Annahmen optimieren über Zeigerverhalten. Da u32 und u64 unterschiedliche Typen sind, geht der Compiler davon aus, dass sie nicht auf denselben Speicher verweisen und dass die über die u32-Zeiger vorgenommenen Änderungen keinen Einfluss auf den Wert von tmp haben. Diese Optimierung führt zum beobachteten Verhalten.
Lösungen zur Erhaltung des Funktionsverhaltens
Um zu verhindern, dass der Code herausoptimiert wird, sollten die Zeigertypen mit den Datentypen übereinstimmen, auf die zugegriffen wird. Ein Ansatz besteht darin, eine Union zu verwenden, um direkt auf die Bits zuzugreifen:
typedef union { uint32_t u32; uint16_t u16[2]; } U32; uint32_t swap_words(uint32_t arg) { U32 in; uint16_t lo; uint16_t hi; in.u32 = arg; hi = in.u16[0]; lo = in.u16[1]; in.u16[0] = lo; in.u16[1] = hi; return (in.u32); }
Durch die Verwendung einer Union stellen wir sicher, dass die Zeiger und Datentypen kompatibel sind, und verhindern so, dass der Compiler die beabsichtigten Änderungen herausoptimiert.
Das obige ist der detaillierte Inhalt vonWarum unterbricht die Compiler-Optimierung diese 64-Bit-Swap-Funktion?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!