2009-05-18 13 views
19

J'ai lu sur les extensions du jeu d'instructions x86, et elles ne semblent utiles que dans certaines circonstances bien spécifiques (par exemple HADDPD - (Horizontal-Add-Packed-Double) dans SSE3). Ceux-ci nécessitent une certaine configuration de registre qui doit être soit délibérément mise en place, ou se produire à partir de la série d'instructions avant elle. À quelle fréquence les compilateurs à usage général comme gcc utilisent-ils réellement ces instructions (ou un sous-ensemble de ceux-ci), ou sont-ils principalement destinés à être utilisés dans un assembleur codé à la main? Comment le compilateur détecte-t-il l'utilisation des instructions SIMD?Comment les compilateurs modernes utilisent-ils les instructions mmx/3dnow/sse?

Répondre

22

Généralement, peu de compilateurs les utilisent. GCC et Visual Studio ne sont généralement pas en mesure d'utiliser les instructions SIMD. Si vous activez SSE en tant qu'indicateur de compilateur, il utilisera les instructions SSE scalaires pour les opérations à virgule flottante normales, mais en général, ne vous attendez pas à ce que les instructions vectorisées soient utilisées automatiquement. Les versions récentes de GCC pourraient être en mesure de les utiliser dans certains cas, mais n'ont pas fonctionné la dernière fois que j'ai essayé. Le compilateur C++ d'Intel est le seul grand compilateur que je connaisse capable de vectoriser automatiquement certaines boucles.

En général, vous devrez les utiliser vous-même. Soit dans l'assembleur brut, soit en utilisant les intrinsèques du compilateur. En général, je dirais que les intrinsèques sont la meilleure approche, car ils permettent au compilateur de mieux comprendre le code, et ainsi planifier et optimiser, mais en pratique, je sais que MSVC ne génère pas toujours du code très efficace à partir des intrinsèques, si simple que cela puisse être la meilleure solution. Expérimenter, voir ce qui fonctionne. Mais ne vous attendez pas à ce que le compilateur utilise ces instructions pour vous, sauf si vous 1) utilisez le bon compilateur et 2) écrivez des boucles assez simples qui peuvent être trivialement vectorisées.

Mise à jour 2012
Ok, donc trois ans se sont écoulés depuis que j'ai écrit cette réponse. GCC a été en mesure d'auto-vectoriser le code (simple) pour quelques années maintenant, et dans VS2012, MSVC finalement gagne la même capacité. Bien sûr, la partie principale de ma réponse s'applique toujours: les compilateurs ne peuvent toujours que vectoriser un code assez trivial. Pour quelque chose de plus complexe, vous êtes coincé avec l'intrication intrinsèque ou inline.

+0

Est-ce que les intrinsèques sont devenus (beaucoup) meilleurs ces dernières années? La dernière fois que j'ai vérifié, MSVC et ICC avaient une allocation de registre assez moche, et même j'étais facilement capable de battre la version intrinsèque du compilateur avec un assemblage codé à la main. – snemarch

+0

Je crois que les versions récentes de MSVC ont apporté * quelques * améliorations au code généré par intrinsèques. Mais je ne sais pas quelle différence cela a fait. – jalf

+0

La sortie de MSVC pour SSE scalaire est toujours juste terrible, surtout si vous utilisez un intrinsèque n'importe où. – Crashworks

-10

Je ne les utiliserais probablement pas si je le pouvais. Méfiez-vous des incompatibilités Intel/AMD. Ce peut être un conseil obsolète maintenant, ou peut-être pas. Je n'ai aucun moyen de le dire.

EDIT: obsolète, probablement de très longue durée.

+0

C'est une raison assez faible pour éviter de telles instructions. Ils n'existeraient pas s'ils ne servaient pas un but. –

+0

Vous avez un compilateur qui fait les deux ensembles TURBO? Je ne suis pas sûr. – Joshua

+0

Ceci est juste incorrect, tous les processeurs Intel et AMD modernes, et tous les compilateurs modernes (GCC, VS) supportent SSE et MMX. – Zifre

4

La question de savoir comment exploiter SSE et d'autres petites unités de vecteur automatiquement (sans direction du programmeur sous la forme de constructions linguistiques spéciales ou compilateur spécialement béni « intrinsics ») a été un sujet de recherche compilateur pour un certain temps. La plupart des résultats semblent être spécialisés dans un domaine de problème particulier, tel que digital signal processing. Je n'ai pas suivi la littérature sur ce sujet, mais ce que a lu suggère que l'exploitation de l'unité vectorielle (SSE) est toujours un sujet de recherche, et que l'on devrait avoir de faibles attentes de compilateurs à usage général couramment utilisés dans le champ.

terme de recherche suggéré: compilateur vectorisation

0

Si vous utilisez le compilateur vecteur pascals vous obtiendrez un code efficace SIMD pour les types pour lesquels SIMD donne un avantage. Fondamentalement, tout cela est de longueur inférieure à 64 bits. (pour les réels de 64 bits, il est en fait plus lent de faire SIMD). Les dernières versions du compilateur paralléliseront automatiquement les cœurs

+0

64 bits réels, aka 'double', bénéficie de SIMD sur n'importe quel CPU avec SSE2, sauf peut-être Pentium-M/Core Solo où 128b vectoriels ont été divisés en deux moitiés de 64 bits, et les instructions multi-uop causent des goulots d'étranglement. Sur n'importe quoi après Core2 ou AMD K10, SIMD est une victoire claire pour 'double 'aussi bien. –