je me trouve confronté à un problème que je ne peux pas comprendre. Je le soumets ici à vos idée, réflexions, explications …
J’ai un code fortran monoprocesseur compilé avec ifort sans options particulières, qui tourne beaucoup plus vite sur mon Intel Core2 Duo à 2.4 Ghz que sur un i7 tout neuf à 2.8 Ghz … Pour exemple, un calcul test me prends ~8 minutes sur le Core2 Duo, et ~200 minutes sur le i7. Je précise que le i7 est la version i7 M640 (sur un pc portable, donc à 2 coeurs, hyperthreadé à 4 threads max).
J’ai déjà effectué de nombreux tests: changements d’OS, changements de compilateurs, changements d’options de compilations (-O2, -O3 …), désactiver l’hyperthreading, le IntelTurbo du bios … Rien n’y fait, mon i7 est lent
J’ai l’impression de ne pas arriver à utiliser correctement la machine, quelqu’un a-t-il une idée ? Je pense qu’il y a forcément un problème d’utilisation pour voir une telle dégradation des performances.
Le processeur à lui seul ne fait les performances globales d’un machine.
Le type et la vitesse de la mémoire peut jouer, tout comme les disques, le chipset, …
Les deux machines sont des ordinateurs portables ?
La mémoire et le disque sont-ils les mêmes ?
Acpi, cpufreq ou équivalent d’installé sur les machines ?
C’est un problème intéressant. Mais tout de même, passer de 8 minutes à 200 minutes, il t’est légitime de poser des questions ! Doooh (comme dirait un célèbre personnage de dessin animé à la peau jaune)!
Les données que tu charges en mémoire sont importantes? Quels autres éléments de comparaison — et pouvant jouer sur cette belle performance de temps CPU — entre les 2 PCs as-tu? Le code est-il parallélisé?
Affaire à suivre… Et puis bravo pour ta patience. Attendre 200min quand on s’attend à moins de 8min !
Dell Studio 15 (1555) - Intel Core2 duo @2.4 Ghz - 4 Go de Ram
Dell Precision M4500 - Intel i7 M640 @2.8 Ghz - 4Go de ram (de mémoire, je n’ai pas sous les yeux - je corrigerai si besoin)
Le Studio15 a bientôt 3 ans, et est plus bien plus rapide que le Precision M4500 tout neuf …
Acpi, cpufreq ou équivalent d'installé sur les machines ?
Je ne comprends pas bien la question … Sur les deux machines j’ai Debian Squeeze 64b installé, avec à peu de choses près la même config.
bejazzy
C’est clair … dohhh. Surtout ça me fait mal de lancer mes calculs sur mon anciens pc en regardant mon pc tout neuf ne rien faire surtout que, comme tu le dis, la différence n’est pas minime …
C’est un problème qui me travaille depuis un moment, et je ne suis pas seul sur le coup (on est deux à avoir le même pc au bureau …). Donc nous avons vraiment essayé beaucoup de choses …
Pour ma part, j’ai exactement la même configuration software (je pense) sur les deux machines … pour justement limiter les différences entre les deux machines…
J’ai également effectué les tests sur un Xeon @2.33 Ghz, les résultats s’approchent du Core2 duo (~ 13 minutes pour mon calcul test). Je ne vois absolument pas d’où a peut venir, j’ai l’impression d’avoir épuisé toutes les pistes de mon coté …
Acpi et CpuFreq sont des paquets que tu peux installer sur un système Debian et autre.
Ils agissent sur la gestion de l’énergie et peuvent brider la puissance de ton processeur juste pour consommer moins.
Pour savoir s’ils sont installés sur tes machines, utilise la commande suivante :
Et au passage un :
sur les deux machines serait intéressant.
Autre point, sur le I7, il n’aurait pas un autre processus qui consommerait des ressources et qui donc ferait chuter les performances de ton code ?
Sur les deux machines au moment de l’exécution du code.
Bah, s’il a quatre threads sur son i7, et que son code est mono-thread, même un ou deux autres processus lourds ne devraient pas induire une telle différence (25 fois, quand même, c’est colossal)…
Petites questions :
Apparemment, tu as essayé plusieurs compilateurs différents ? Parce que ça me fait quand même furieusement penser à une incompatibilité entre compilateur et architecture (mauvaise gestion de ce « nouveau » CPU)… As-tu essayé gfortran (dans ses différentes versions) ?
As-tu essayé avec un autre code ? Ou en reprenant celui de ton appli, mais en le “découpant” pour en tester chaque partie, et essayer de voir celle(s) qui pose(nt) problème (si c’est possible, évidemment…) ?
As-tu essayé ton code sur une autre machine (avec un i7, mais d’autres CM/mémoire/chipset) ?
Problème intéressant. Il serait pratique d’avoir un profileur pour voir.
Acpi c’est de la daube, le mieux c’est de recompiler son noyau en lui indiquant d’une part que tu as une CPU intel (un driver qui outre passe l’Acpi et qui permet de gérer convenablement tout les états d’endormissements de la CPU quelque soit la DSDT), d’autre part même si ça a moins d’impact le compiler pour Corei7.
Ensuite pour vérifier si c’est un problème d’environnement je serais toi je lancerais le calcul sur les deux machines et je regarderais le load average en fin de calcul.
Ensuite comme le dis mont c’est peut être un problème du compilateur (tente avec le compilateur inclus dans gcc en version 4.6) à ce compilateur aide-le en lui donnant un max d’informations sur ta machine. Je te conseil la lecture de ce commentaire sur linuxfr : linuxfr.org/news/la-version-46-d … nt-1221248
J’en recopie une partie pour dupliquer l’information sur le net :
D’abord, merci à tous pour toutes ces propositions et votre intérêts envers mon problème.
[quote=“Niloo”]Code:
dpkg -l | egrep ‘acpi|cpu’
Et au passage un :
Code:
cat /proc/cpuinfo
sur les deux machines serait intéressant.
Autre point, sur le I7, il n’aurait pas un autre processus qui consommerait des ressources et qui donc ferait chuter les performances de ton code ?
Code:
top -n1
Sur les deux machines au moment de l’exécution du code.[/quote]
Je te donne tous les résultats de ces commandes dès ce soir, là je n’ai qu’un seul des deux pc sous la main. Il n’empêche que :
je crois bien que cpufreq et acpi sont installés sur les deux machines,
je surveille la charge de mon processeur par l’applet disponible dans le tableau de bord. Sur mon i7, j’ai bien une charge à 25% (normal, je lance un code mono-thread sur un 4 threads …) et sur mon core2 duo, j’ai bien 50% (idem, code mono-thread sur un bi-coeurs …). Dans tous les cas, je n’ai pas une surcharge à ce niveau là, puisque toujours des disponibilités de processus …
[quote=“mont”]Petites questions :
Apparemment, tu as essayé plusieurs compilateurs différents ? Parce que ça me fait quand même furieusement penser à une incompatibilité entre compilateur et architecture (mauvaise gestion de ce « nouveau » CPU)… As-tu essayé gfortran (dans ses différentes versions) ?[/quote]
Je vais refaire mes tests pour en être sûr, et avoir des chiffres précis. C’était en effet, ma première idée à moi aussi …
En fait, ça ressemble a du profilage ce que tu me proposes. Dans l’absolu, je sais que mon code a des problèmes d’optimisations, mais je pensais que ce n’était pas ce problème. Je n’ai pas essayé en effet, ça pourrait être une idée pour résoudre le problème, mais penses-tu vraiment que le même code non optimisé peut voir apparaître de telles différences sur ces 2 machines ?
Je ne l’ai pas fait, et c’est une très bonne idée. Je vais essayer de trouver une machine de ce type pour faire ce test
MisterFreez, je me lance dans la lecture de ton lien, merci beaucoup.
Je vous tiens informés de la suite des évènements Merci à tous !
En fait, ça ressemble a du profilage ce que tu me proposes. Dans l’absolu, je sais que mon code a des problèmes d’optimisations, mais je pensais que ce n’était pas ce problème. Je n’ai pas essayé en effet, ça pourrait être une idée pour résoudre le problème, mais penses-tu vraiment que le même code non optimisé peut voir apparaître de telles différences sur ces 2 machines ?[/quote]
En fait avec cette technique tu peut remarquer un endroit du code qui est beaucoup plus lourd que les autres et qui correspondrait à l’endroit où tu utilise des ressources moins efficace sur ta nouvelle machine que sur la précédente.
Humhum, merci pour l’explication Mr Freeze, je ne voyait pas ça sous cet oeil …
sinon, il est possible (sans vouloir crier victoire trop vite), que dans tous mes précédents tests, certaines choses m’aient échappées : je viens de re-tester mon calcul avec gfortran et je re-considérer fortement la thèse du compilateur défectueux.
Sur le i7 M640@2.8Ghz : Le calcul passe donc de 200 min avec ifort à 19 min avec gfortran … Sur le Xeon @2.33Ghz : Le calcul passe donc de 13 min avec ifort à 30 min avec gfortran …
Me reste à comprendre qu’est ce qui est défectueux dans le compilateur fortran et quelles options mettre sur mon i7 pour tirer avantages de ifortran …
Je vais ajouter une petite avancée dans mes recherches :
Sur le i7 M640@2.8Ghz : Le calcul passe donc de 200 min avec ifort à 19 min avec gfortran à 8:46 min en ajoutant l’option -O3 à gfortran …
Sur le Core2 Duo@2.4Ghz (config initiale) : Le calcul fait 8:16 min avec ifort (sans -O3) et 11:15 min avec ifort (avec -O3)
J’ai donc l’impression que ifort utilise des options par défauts qui me font vraiment défaut sur le i7 …
Ben, il me semble effectivement que le problème est avec ifort. Si tu as vraiment la dernière version de cet outil, j’ai comme l’impression qu’Intel se fiche du monde, s’ils ne sont même pas foutus de coder un compilateur qui marche sur leurs processeurs les plus récents…
Sinon, tu peux ajouter l’option -march=native à gfortran, pour avoir une optimisation maximale (attention, le binaire produit ne sera alors sûrement pas portable sur d’autres types de CPU).
cette partie du problème est résolu : je déconseille fortement à tout un chacun d’utiliser la fonction rand() de gfortran mais de lui préférer random_number(). La différence de résultats entre les deux compilateurs venait de là. Mon programme fait de nombreux appels à des nombres aléatoires et donc les limites de rand() sont vite atteintes.
EDIT : le problème de vitesse de ifort reste ouvert …
Je vais être plus précis : mon programme représente un phénomène physique, le mouvement brownien en l’occurrence, qui est un phénomène dit “aléatoire”. C’est pourquoi j’utilise la génération de nombres aléatoires. En outre, on connaît pas mal de choses sur ce type de mouvement (brownien) et la physique étant ce qu’elle est, je valide mon code sur un certains nombre de statistiques, qui doivent être toujours les mêmes …
Donc oui, j’utilise des nombres aléatoires, mais non, je ne dois pas obtenir des résultats aléatoire
De plus, la génération de nombre pseudo-aléatoire dans un code de calcul est une science à part entière, très complexe. Il faut respecter de nombreux critères pour que le programme voit “réellement” des nombres aléatoire et non une suite de nombres récurrente. C’est pourquoi rand() n’est pas bon, et random_number() est, disons … meilleur.
Enfin, dernière chose à savoir : par défaut, deux exécutions d’un même programme qui utilise la génération de nombres pseudo-aléatoires doivent donner exactement le même calcul : c’est reproductible. Ça vient du fait que les fonctions rand() et random_number() génèrent en fait des suites de nombres aléatoires partant de ce que l’on appel une graine (une valeur initiale si tu préfères …). Si cette valeur reste inchangée, la suite fournie par les fonctions est exactement la même
Donc aléatoire oui, mais pas n’importe comment
Petite parenthèse qui ne résout en rien (ni même ne fait avancer) le problème.