Pourquoi l'optimisation dégrade cette fonction
Lors d'une conférence universitaire sur les spécialités de programmation, un professeur a présenté une fonction qui a dérouté les étudiants :
inline u64 Swap_64(u64 x) { u64 tmp; (*(u32*)&tmp) = Swap_32(*(((u32*)&x)+1)); (*(((u32*)&tmp)+1)) = Swap_32(*(u32*) &x); return tmp; }
Au départ, la fonction fonctionnait sans problème, mais après avoir activé des niveaux d'optimisation élevés, elle est devenue inerte. La raison derrière ce comportement réside dans le concept de règles d'alias strictes.
Violation d'alias stricte
Le code fourni viole des règles d'alias strictes, qui dictent que les objets ne doivent être accessible via des types de pointeurs compatibles. Dans ce cas, les pointeurs u32 et u64 pointent vers une mémoire potentiellement superposée, mais le compilateur suppose qu'ils représentent des objets distincts. Cette hypothèse lui permet d'optimiser les affectations à la variable temporaire tmp, rendant la fonction inefficace.
Pourquoi l'optimisation se produit
Le compilateur est autorisé à optimiser le code en fonction d'hypothèses sur le comportement du pointeur. Puisque u32 et u64 sont de types différents, le compilateur suppose qu'ils ne pointent pas vers la même mémoire et que les modifications apportées via les pointeurs u32 n'affecteront pas la valeur de tmp. Cette optimisation conduit au comportement observé.
Solutions pour préserver le comportement des fonctions
Pour éviter que le code ne soit optimisé, les types de pointeurs doivent correspondre aux types de données consultés. Une approche consiste à utiliser une union pour accéder directement aux bits :
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); }
En utilisant une union, nous nous assurons que les pointeurs et les types de données sont compatibles, empêchant le compilateur d'optimiser les modifications prévues.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!