Question

Quelqu'un at-il profité de la vectorisation automatique que gcc peut faire? Dans le monde réel (par opposition à l'exemple de code)? Faut-il restructurer le code existant pour en tirer parti? Existe-t-il un nombre significatif de cas dans un code de production pouvant être vectorisés de cette manière?

Était-ce utile?

La solution

Je n'ai pas encore vu GCC ni Intel C ++ vectoriser automatiquement autre chose que des boucles très simples, même avec le code des algorithmes qui peuvent (et ont été, après que je les ai réécrits manuellement à l'aide d'intrinsèques SSE) être vectorisés.

Une partie de cela est conservatrice - en particulier face à un possible aliasing de pointeur, il peut être très difficile pour un compilateur C / C ++ de "prouver" à lui-même qu'une vectorisation serait sûre, même si vous, en tant que programmeur, savez que il est. La plupart des compilateurs préfèrent (de manière raisonnable) ne pas optimiser le code plutôt que de risquer de le mal compiler. C’est un domaine dans lequel les langages de niveau supérieur ont un réel avantage sur le langage C, du moins en théorie (je dis en théorie, car je ne suis au courant d’aucun compilateur vectorisant automatiquement ML ou Haskell).

Un autre élément concerne simplement les limites analytiques: la plupart des recherches sur la vectorisation, selon ce que je comprends, portent sur l’optimisation des problèmes numériques classiques (la dynamique des fluides, par exemple), qui était à la base de la plupart des machines vectorielles il y a quelques années (quand , entre CUDA / OpenCL, Altivec / SSE et STI Cell, la programmation vectorielle sous diverses formes est désormais largement disponible dans les systèmes commerciaux).

Il est relativement improbable que le code écrit pour un processeur scalaire soit facile à vectoriser pour un compilateur. Heureusement, beaucoup de choses que vous pouvez faire pour aider un compilateur à comprendre comment le vectoriser, comme la mosaïque et le déroulement partiel de boucles, aident également (généralement) à améliorer les performances sur les processeurs modernes, même si le compilateur ne sait pas comment vectorisez-le.

Autres conseils

Il est difficile à utiliser dans une logique métier, mais accélère lorsque vous traitez des volumes de données de la même manière.

Un bon exemple est le traitement audio / vidéo où vous appliquez la même opération à chaque échantillon / pixel. J'ai utilisé VisualDSP pour cela, et vous deviez vérifier les résultats après la compilation - s'il est vraiment utilisé à l'endroit approprié.

La vectorisation sera principalement utile pour les programmes numériques. Les programmes vectorisés peuvent s'exécuter plus rapidement sur des processeurs vectoriels comme le processeur STI Cell utilisé dans les consoles de jeu PS3. Là, les calculs numériques utilisés pour, par exemple, le rendu des graphiques du jeu peuvent être considérablement accélérés par la vectorisation. Ces processeurs sont appelés processeurs SIMD (Single Instruction Multiple Data).

Sur d'autres processeurs, la vectorisation ne sera pas utilisée. Les programmes vectorisés s'exécutent sur un jeu d'instructions vectorisées qui ne s'appliqueront pas à un processeur autre que SIMD.

Les processeurs Nehalem d’Intel (publiés fin 2008) implémentent les instructions SSE 4.2, qui sont des instructions SIMD. Source: wikipedia .

Les instructions vectorisées ne se limitent pas aux processeurs de cellules - la plupart des processeurs modernes (comme les processeurs) (PPC, x86 depuis le pentium 3, Sparc, etc.). Bien utilisé pour les opérations en virgule flottante, il peut être très utile pour les tâches très intensives en informatique (filtres, etc.). D'après mon expérience, la vectorisation automatique ne fonctionne pas très bien.

Vous avez peut-être remarqué que pratiquement personne ne sait comment utiliser à bon escient la vectorisation automatique de GCC. Si vous effectuez une recherche sur le Web pour consulter les commentaires des internautes, vous en arriverez toujours à l’idée que GCC vous permet d’activer la vectorisation automatique, mais qu’il en fait très rarement une utilisation réelle. Par conséquent, si vous souhaitez utiliser l’accélération SIMD (par exemple: MMX, SSE, AVX, NEON, AltiVec), vous devez donc savoir comment l'écrire à l'aide des éléments intrinsèques du compilateur ou du code du langage d'assemblage.

Mais le problème des éléments intrinsèques est qu’il vous faut comprendre le langage assembleur et apprendre la méthode Intrinsics pour décrire ce que vous voulez, ce qui entraînera probablement un code beaucoup moins efficace que si vous l’écriviez Code d'assemblage (par exemple, multiplié par 10), car le compilateur aura toujours du mal à utiliser vos instructions intrinsèques!

Par exemple, vous pouvez utiliser SIMD Intrinsics pour pouvoir effectuer plusieurs opérations en parallèle simultanément, mais votre compilateur générera probablement un code Assembly qui transfère les données entre les registres SIMD et les registres de la CPU normaux et inversement, pour que votre code SIMD fonctionne à une vitesse similaire (ou même plus lente) que le code normal!

Donc en gros:

  • Si vous voulez jusqu’à 100% d’accélération (2x vitesse), soit acheter le compilateurs officiels Intel / ARM ou convertissez une partie de votre code pour utiliser les technologies intrinsèques SIMD C / C ++.
  • Si vous veulent 1000% d'accélérations (10x vitesse), puis écrivez-le en code d'assemblage à l'aide d'instructions SIMD à la main. Ou, si disponible sur votre matériel, utilisez plutôt l'accélération GPU, telle que OpenCL ou le kit de développement logiciel CUDA SDK de Nvidia, car ils peuvent fournir des accélérations similaires dans le GPU que SIMD dans le processeur.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top