Nouveautés C++ de la preview de Visual Studio 11 partie III

Téléchargement de la CTP de Visual Studio 11

Retrouvez la Partie 1

Retrouvez la Partie 2

Retrouvez la Partie 4

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

  1. for (int i=0;i <MAX_;i++)
  2.     {
  3.         a[i]=i*7.0;
  4.     }

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

  1. ; 38   :     for (int i=0;i <MAX_;i++)
  2.  
  3.     fld    QWORD PTR __real@401c000000000000
  4.     add    esp, 4
  5.     mov    esi, eax
  6.     xor    eax, eax
  7.     mov    DWORD PTR _i$83361[ebp], eax
  8. $LN3@wmain:
  9.  
  10. ; 39   :     {
  11. ; 40   :         a[i]=i*7.0;
  12.  
  13.     fild    DWORD PTR _i$83361[ebp]
  14.     inc    eax
  15.     mov    DWORD PTR _i$83361[ebp], eax
  16.     fmul    ST(0), ST(1)
  17.     fstp    QWORD PTR [esi+eax*8-8]
  18.     cmp    eax, 100000000                ; 05f5e100H
  19.     jl    SHORT $LN3@wmain
  20.  
  21. ; 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

  1. ; 38 : for (int i=0;i <MAX_;i++)
  2.  
  3.     movsd xmm1, QWORD PTR __real@401c000000000000
  4.     add esp, 4
  5.     mov esi, eax
  6.     xor ecx, ecx
  7.     npad 5
  8. $LL9@wmain:
  9.  
  10. ; 39 : {
  11. ; 40 : a[i]=i*7.0;
  12.  
  13.     movd xmm0, ecx
  14.     cvtdq2pd xmm0, xmm0
  15.     inc ecx
  16.     mulsd xmm0, xmm1
  17.     movsd QWORD PTR [esi+ecx*8-8], xmm0
  18.     cmp ecx, 100000000 ; 05f5e100H
  19.     jl SHORT $LL9@wmain
  20.  
  21. ; 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)

image

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

image

Avec les instructions

image

 

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.

image

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é