[C++] Visual Studio 2012, mot-clef “auto” et alignement mémoire
En C++, on peut poser sur nos classes et structures des contraintes d’alignement mémoire (sous visual studio, on utilise __declspec(align(<alignement souhaité>))).
Cela permet certaines optimisations (par exemple en faisant en sorte que les différents champs d’une structure soient tous contenus dans la même ligne de cache), mais surtout, cela est nécessaire pour manipuler les fonctions SSE/AVX des processeurs x86 modern, et NEON des processeurs ARM qui ne savent travailler qu’avec des structures de données alignées sur 16 octets. Ces instructions permettent d’effectuer des opérations vectorielles en une seule instruction processeur (additions, multiplication de vecteurs et matrices…), et sont donc très utilisées dans les programmes faisant du calcul intensif et dans le jeu vidéo. Microsoft fournit d’ailleurs une librairie mathématique très pratique exploitant les instructions Intel SSE et ARM Neon : DirectXMath suivant l’architecture ciblée.
DirectXMath fournit donc des types XMVECTOR et XMMATRIX qui ont une contrainte d’alignement spécifiée à 16. Si j’écrit XMVECTOR monVecteurSSE = ConstruitUnVecteurAPartirDuneFormuleMathématiqueComplexe(), j’ai donc la garantie que “monVecteurSSE” aura une adresse multiple de 16.
Mais un bug dans le compilateur de Visual Studio fait que si j’écris auto monVecteurSSE = ConstruitUnVecteurAPartirDuneFormuleMathématiqueComplexe(), la contrainte d’alignement est ignorée ! Cela peut produire des bugs très compliqués à analyser (le problème ne se posant pas de manière systématique), qui se traduisent parfois par des crashs, parfois par des erreurs mathématiques…
La solution de contournement est donc de proscrire l’utilisation du mot clef “auto” dans les portions de code nécessitant un alignement mémoire des données particulier.
Commentaires