Nouveautés C++ de la preview de Visual Studio 11 partie III
Téléchargement de la CTP de Visual Studio 11
Auto-vectorizer
Dans la documentation MSDN, il est noté que désormais le compilateur pour des raisons de performances est capable de “vectoriser” automatiquement une boucle et qu’une boucle peut-être 8 fois plus rapide sur les processeurs qui support les instructions SIMD, ce qui est la majorité des cas pour tous les processeurs X86/X64 modernes.
Dans Visual Studio 2010, pour activer ses instructions, il fallait penser à rajouter l’option de compilation /arch:SSE /arch:SS2
Avec la preview de Visual Studio 11, l’utilisation des instructions SIMD et des registres associés ce fait automatiquement.
Avec Visual Studio 2010, la boucle suivante en C/C++
Code Snippet
- for (int i=0;i <MAX_;i++)
- {
- a[i]=i*7.0;
- }
donne le code assembleur suivant qui utilise les instructions et les registres permettant de manipuler des floats. (fld,fild,fmul,fstp,fstp, ST(0),ST(1) )
Code Snippet
- ; 38 : for (int i=0;i <MAX_;i++)
- fld QWORD PTR __real@401c000000000000
- add esp, 4
- mov esi, eax
- xor eax, eax
- mov DWORD PTR _i$83361[ebp], eax
- $LN3@wmain:
- ; 39 : {
- ; 40 : a[i]=i*7.0;
- fild DWORD PTR _i$83361[ebp]
- inc eax
- mov DWORD PTR _i$83361[ebp], eax
- fmul ST(0), ST(1)
- fstp QWORD PTR [esi+eax*8-8]
- cmp eax, 100000000 ; 05f5e100H
- jl SHORT $LN3@wmain
- ; 41 : }
avec Visual Studio 11 la même boucle par défaut donne en assembleur le code suivant qui utilise des instructions et des registres propres à la vectorisation. (movsd, mulsd, cvtdq2pd, xmm0, xmm1)
Code Snippet
- ; 38 : for (int i=0;i <MAX_;i++)
- movsd xmm1, QWORD PTR __real@401c000000000000
- add esp, 4
- mov esi, eax
- xor ecx, ecx
- npad 5
- $LL9@wmain:
- ; 39 : {
- ; 40 : a[i]=i*7.0;
- movd xmm0, ecx
- cvtdq2pd xmm0, xmm0
- inc ecx
- mulsd xmm0, xmm1
- movsd QWORD PTR [esi+ecx*8-8], xmm0
- cmp ecx, 100000000 ; 05f5e100H
- jl SHORT $LL9@wmain
- ; 41 : }
Est-ce qu’il est possible de désactiver cette fonctionnalité ?
Oui il suffit d’aller dans les propriétés du projet, C++ | Code Generation | Enable Enhanced Instruction Set et de choisir No Enhanced Instructions (/arch:IA32) comme indiqué sur la figure suivante (par défaut il est à Not Set, ce qui veut dire que l’auto vectorisation est activée)
Sur ma machine de test, le Not Set, correspond à /arch:SSE2.
Vous noterez également que la VS 11 gère désormais les nouvelles instructions AVX
Est-ce que cela à une incidence sur les performances ?
Oui sur 1 million d’itérations, j’obtient une optimisation substantielle sur ma simple boucle
Sans les instructions
Avec les instructions
Auto-parallelizer
Dans la documentation il est indiqué qu’il est désormais possible de tirer profit des machines multi-processeur à l’aide d’une nouvelle fonctionnalité de VS 11, le parallelizer, qui serait capable de réorganiser les boucles pour les éclater sur plusieurs cœurs. La nouvelle instruction /Qpar est disponible pour activer cette fonctionnalité, en association avec un #pragma qui identifie la boucle à paralléliser et que le développeur doit indiquer.
Néanmoins à l’heure ou je vous parle, un bug dans l’installation de la preview de Visual Studio 11, ne permet pas d’investiguer plus en détail. J’y reviendrais donc dans un prochain Billet.
C++ Accelerated Massive Parallelism (AMP) Support
Depuis Visual Studio 2010, nous avons accès à des libraires (PPL) qui permettent de simplifier le développement parallèle, Je ne reviens pas dessus, nous y consacrons l’intégralité d’un blog https://blogs.msdn.com/b/devpara
Avec VS 11 il sera également possible de tirer profit des possibilité des cartes graphiques, dans le cadre du GPGPU. En d’autres termes, il sera possible de mixer du code traditionnel CPU et du code GPU dans une syntaxe familière et plus simple a appréhender. Encore une fois je ne rentre pas dans le détail, car Bruno Boucard mon compère du blog devpara, y consacre plusieurs billets, que je vous encourage à aller voir.
Eric Vernié