37 votes

Pourquoi les processeurs Intel Haswell XEON calculent-ils sporadiquement des FFT et des traitements ART?

Durant les derniers jours, j'ai observé un comportement de mon nouveau poste de travail je ne pouvais pas expliquer. En faisant quelques recherches sur ce problème, il y a peut être un bug possible dans l' INTEL Haswell d'architecture ainsi que dans le courant de Skylake Génération.

Avant d'écrire sur le bug possible, laissez-moi vous donner un aperçu du matériel utilisé, le code du programme et le problème lui-même.

Poste de travail de spécification du matériel

  • INTEL Xeon E5-2680 V3 2500MHz 30M Cache 12Core
  • Supermicro SC745 BTQ -R1K28B-SQ
  • 4 x 32 GO Enregistrée ECC DDR4-2133 Ram
  • INTEL SSD 730 Series 480 GO
  • NVIDIA Tesla C2075
  • NVIDIA TITAN

Système d'exploitation et le code du programme en question

Je suis actuellement sous Ubuntu 15.04 64 bits version de Bureau, les dernières mises à jour du noyau et des trucs installé. Outre l'utilisation de cette machine à développer des Noyaux CUDA et d'autres choses, j'ai récemment testé une pure C programme. Le programme est en train de faire le tri de toutes les modifications de l'ART sur la très grande entrée ensembles de données. Ainsi, le code s'exécute certains Fft et consomme très peu de temps pour terminer le calcul. Je ne peux pas actuellement de poste / lien vers n'importe quelle source du code est en cours de recherche qui ne peuvent pas être publiés. Si vous n'êtes pas familier avec l'ART, juste une explication simple de ce qu'il fait. L'ART est une technique utilisée pour reconstruire les données reçues à partir d'un ordinateur ct-scan de la machine pour obtenir des images visibles pour le diagnostic. Donc, notre version du code reconstitue des ensembles de données de tailles comme 2048x2048x512. Jusqu'à maintenant, rien de spécial, ni la science de fusée impliqués. Après quelques heures de débogage et de corriger les erreurs, le code a été testé sur les résultats de référence et nous pouvons confirmer que le code fonctionne comme il est censé le faire. La seule bibliothèque le code, c'est la norme math.h . N ° spécial de la compilation des paramètres, aucune autre bibliothèque de trucs qui pourraient apporter un supplément de problèmes.

En observant le problème

Le code met en œuvre d'ART à l'aide d'une technique pour réduire les projections nécessaires pour reconstruire les données. Supposons donc que nous pouvons reconstruire la tranche de données regroupant 25 projections. Le code est commencé avec exactement les mêmes données d'entrée sur les 12 cœurs. Veuillez noter que l' la mise en œuvre n'est pas basé sur le multithreading, actuellement 12 instances du programme sont lancés. Je sais que ce n'est pas la meilleure façon de le faire, impliquant bon thread de gestion est fortement conseillé et c'est déjà sur la liste des améliorations :)

Alors, quand nous courons au moins deux instances du programme (chaque instance de travail sur une autre tranche de données), les résultats de certaines projections sont mauvais sur un mode aléatoire. Pour vous donner une idée des résultats, veuillez consulter le tableau 1. Veuillez noter que les données d'entrée est toujours le même.

L'exécution d'une seule instance du code portant sur un core du CPU, les résultats sont tout à fait correct. Même effectuer quelques essais impliquant un cœur de PROCESSEUR, les résultats restent corrects. Seulement, impliquant au moins deux ou plusieurs noyaux génère un résultat motif comme on le voit dans le tableau 1.

Table1: randomly wrong results from Haswell XEON CPU

L'identification du problème

Bon ce a fallu que quelques heures pour avoir une idée de ce qui se passe réellement mal. Nous sommes donc allés à travers l'ensemble du code, la plupart de ces problèmes commencent avec une mineure de la mise en œuvre erreur. Mais, eh bien, pas (évidemment, on ne peut pas la preuve de l'absence de bugs, ni le garantir). Afin de vérifier notre code, nous avons utilisé deux machines différentes:

  • (Machine1) Intel Core i5 Quad-Core (Modèle à partir de fin 2009)
  • (Machine2) de la Machine Virtuelle s'exécutant sur le processeur Intel XEON 6core PROCESSEUR SandyBridge

étonnamment, les deux Machine1 & Machine2 produisent toujours des résultats corrects. Même en utilisant tous les CPU-cœurs, les résultats restent corrects. Même pas un mauvais résultat dans plus de 50 s'exécute sur chaque machine. Le Code a été compilé sur chaque machine cible sans les options d'optimisation ou particulières, les paramètres du compilateur. Donc, en lisant les nouvelles ont conduit à des constats suivants:

Donc, les gens de plus en Prime95 et le nombre de Mersenne Communauté qui semble être le premier à découvrir et identifier ce vilain bug. Référencé offres et des nouvelles de soutenir le soupçon que le problème existe uniquement sous la lourde charge de travail. Suite à mon observation, je peux confirmer ce comportement.

La question(s)

  • Avez-vous / la communauté constaté ce problème sur Haswell des Processeurs ainsi que sur les Processeurs Skylake?
  • Que gcc n'par défaut AVX(2) optimisation (autant que possible), la désactivation de cette optimisation aiderait?
  • Comment puis-je compiler mon code et veiller à ce que tout d'optimisation qui pourraient être affectées par ce bug est éteint? Jusqu'à présent j'ai lu que sur un problème à l'aide de l'AVX2 commande set dans Haswell / Skylake architectures.

Des Solutions?

Bon, je peux désactiver la AVX2 optimisations. Mais cela ralentit mon code. Intel pourrait libérer une mise à jour du BIOS de la carte mère fabrique qui permettrait de modifier le microcode dans les Processeurs Intel. Comme il semble être un matériel de bug, cela peut devenir intéressant, même en mettant à jour le Cpu microcode. Je pense que ça pourrait être une option valable, comme les Processeurs Intel utilisation de certains RISC CDCI traduction mécanismes contrôlés par le Microcode.

EDIT: Techreport.com - Errata invites Intel pour désactiver la TSX, Haswell, les premiers Processeurs Broadwell Permettra de vérifier la version de microcode dans mon CPU.

EDIT2: dès maintenant (19.01.2016 15:39 GMT), Memtest86+ v4.20 est en cours d'exécution et le test de la mémoire. Comme cela semble être assez de temps pour terminer, je vais mettre à jour le post demain avec les résultats.

EDIT3: dès maintenant (21.01.2016 09:35 heure de paris) Memtest86+ fini deux courses et passé. Même pas une erreur de mémoire. Mis à jour le microcode du PROCESSEUR de revision=0x2d de revision=0x36. Actuellement en train de préparer le code source pour libérer ici. Problème avec le mauvais résultats est. Comme je ne suis pas l'auteur du code en question, j'ai vérifier de ne pas poster de code je ne suis pas autorisé à le faire. Je suis également en utilisant le poste de travail et à la maintenance.

EDIT4: (22.01.2016) (12:15 CET) Ici ist le Makefile utilisé pour compiler le code source:

# VARIABLES ==================================================================
CC = gcc
CFLAGS = --std=c99 -Wall
#LDFLAGS = -lm -lgomp   -fast -s -m64 
LDFLAGS = -lm 

OBJ = ArtReconstruction2Min.o


# RULES AND DEPENDENCIES ====================================================

# linking all object files
all: $(OBJ)

    $(CC) -o ART2Min $(OBJ) $(LDFLAGS)         


# every o-file depends on the corresonding c-file, -g Option bedeutet Debugging Informationene setzen
%.o: %.c
    $(CC)  -c -g $<  $(CFLAGS)


# MAKE CLEAN =================================================================
clean: 
    rm -f *.o
    rm -f main

et l' gcc -v sortie:

gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.2-10ubuntu13' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13) 

8voto

semm0 Points 693

EDIT: Problème résolu. J'ai du crier un énorme Désolé pour la communauté et un grand merci à vous pour vos conseils. Désolé pour l'utilisateur anonyme, qui semble être impliqué dans le développement du noyau. Ce qui s'est passé? Nous avons passé 2 jours de débogage et de bidouiller avec le code du programme. Pas de problèmes de mise en œuvre ont été trouvés. MAIS: le code principal implique un autre programme d'assistance. Ce programme d'aide programme calcule le poids de l'ART algorithme sur demande. Ainsi, après le débogage et de test, ce programme d'assistance foiré, lors de l'exécution d'au moins 4 processus. Donc, ce n'était PAS un Noyau / problème matériel, mais un logiciel (accès à la mémoire) problème.

Leçons apprises:

  1. Debug chaque outil qui est impliqué dans le processus de calcul.
  2. Microcode était obsolète. SuperMicro est informé à ce sujet.
  3. Ubuntu 15.04 peut avoir besoin d'outils supplémentaires, de sorte que tous les Cœurs du CPU à pleine vitesse. Réalisé par l'installation de Ubuntu 14.04 - tous les cœurs fonctionnant à 2,5 GHz.
  4. J'ai besoin de passé un peu de bière, si jamais nous rencontrer lors d'une conférence.

Ainsi, après trois jours de réflexion, de tests et de bidouiller avec la machine, j'ai découvert la suite des observations d'aujourd'hui:

  1. Ubuntu 15.04 exécute le CPU avec 420 - 650 MHz par Cœur. Ok, je pensais que c'est une économie d'Énergie de l'option, j'ai donc suivi les différents guides pour régler la vitesse au maximum (2.50 GHz). Il n'a pas de travail. Vérifié avec cpufreq-utils.

  2. Les résultats restaient encore mal, après plusieurs tests sur cette machine. D'autres (i5, i7, XEON) les machines a produit des résultats corrects.

  3. J'ai lu que d'autres utilisateurs expérimenté des problèmes avec Ubuntu 15.04 et la fréquence du CPU. J'ai donc décidé de brancher un SSD et installer Ubuntu 14.04. Vérifier à nouveau que la fréquence du CPU est maintenant.. et elle a montré à 2.50 GHz comme je m'y attendais.

  4. De nouveau commencé à l'algorithme de reconstruction (qui a maintenant 4 à 5 fois plus rapide que sur Ubuntu 15.04) et attendait les résultats. Ok. Les résultats sont corrects maintenant! J'ai vérifié, a commencé à 9 processus et de comparer les résultats. Toujours correcte.

Donc, je ne peux que supposer qu'il pourrait y avoir un problème dans Ubuntu 15.04 / noyau à l'aide de Speedstep dans ce CPU. CPU dans 15.04 a couru tout le temps entre 420 et 650 MHz, tandis que le min la vitesse du PROCESSEUR est prévu pour être 1,20 GHz et le max de la vitesse du PROCESSEUR est de 3,30 GHz. Si quelqu'un veut le vérifier, je peux offrir le code source et les données de l'exemple conduisant à ce problème.

Désolé de penser que ce sera un CPU bug.

EDIT: après quelques tests supplémentaires, le problème est résolu pour certains scénarios, mais pas encore pour tous. Je vais faire d'autres tests.

7voto

anonymous Points 59

Les Skylake-S/U prime95 erratum est dans l'AVX (pas AVX2) de l'unité. Il est fixé sur les microcodes 0x56 (probablement) et 0x6a (pour être sûr). Ces erratum dans Haswell est peu probable, mais possible (surtout sur le post-2014 Intel, où la "validation" est devenu une fâcheuse coût à la place d'un locataire de qualité).

Haswell a errata lié à l'AVX l'unité, mais HSE58 est assez peu probable au jeu (il ne ralentit l'AVX unité). Cependant, essayez de placer un peu de MFENCE les instructions avant l'AVX2 calculs. Si cela résout-il, de rendre compte immédiatement, cela signifie que nous devons MFENCE tous IRET dans le noyau (HSE105).

Votre processeur a la signature 0x306f2. Vous assurer que vous avez de microcode de révision 0x36 ou plus tard, ce microcode est d'Intel "Linux mise à jour de microcode pack" de 2015-11-06.

EDIT: ce n'était pas vraiment une réponse, donc je devrais en avoir fait un commentaire, à la place. Je prie de m'excuser. Depuis la mise à jour de microcode n'était pas suffisant pour résoudre le problème, il pourrait encore être une nouvelle errata, une vieille, mais formulé autour d'errata, ou tout autre chose (comme le code bug ou gcc génération de code bug).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X