Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 31/07/2006, à 14:58

jobherzt

bi processeurs

bonjour a tous !!

je vous expose brievement le contexte : je developpe une petite appli en c++ qui realise un calcul pour un groupe de chercheur en chimie.. pour l'instant, ca tournait sur l'ordi windows d'un des collegues, et on vient de se faire offrir l'acces a un ordi bi-processeur 64 bits (sous nunux evidemment, faudrait etre c**)

donc, vu qu'a la base mon appli etait en single thread, je l'ai passée en multi thread..

je n'ai pas beaucoup de detail a propos de cequ'il y a sous le capot, et je n'ai pas d'acces en ssh, le programme est lancé par un des chimiste qui ne s'y connait pas trop en info, encore moins en linux.. donc je dois gerer ca un peu a distance, ce qui m'empeche de bidouiller "a la volée" des trucs et de voir ce qui se passe ( ce qui est quand meme la methode la plus fiable pour faire marcher un truc big_smile )

les premiers test sont bizzares, en plus.. le collegue me certifie que l'ordi a ete 3 fois plus long que son propre ordi avec le prog en single thread, et a peine plus rapide en multi... ca me fait un peu rager..

donc mes quelques questions :
- est ce que le 64 bits apportent qqchose en terme de vitesse de calcul ? si oui quoi ? faut il en tenire compte dans la programmation, ou est ce que ca se passe a la compilation ?
- est ce que pour utiliser les 2 processeurs il faut forcement etre en multi thread ?? (je pense que oui, mais bon... )
- si c'est en multithread, est ce que linux se debrouille comme un grand pour repartir les threads (idem, je pense que oui..) et comment verifier que tout ca marche bien ?
- quelle est la question que j'oublie ? roll ya t il des choses a savoir pour ce genre de bidouilles ?

merci a tous !!

Hors ligne

#2 Le 31/07/2006, à 15:51

Lord Alembert

Re : bi processeurs

Hello.

est ce que le 64 bits apportent qqchose en terme de vitesse de calcul ? si oui quoi ? faut il en tenire compte dans la programmation, ou est ce que ca se passe a la compilation ?

Cela dépend. En général, il ne faut pas trop compter dessus, disons 5~15% de vitesse en plus. Mais dans certains cas, la vitesse peut être franchement supérieure. J'ai programmé en C quelques petites choses pour faire du calcul formel, genre GMP. En 64 bits, la vitesse est presque doublée, car les opérations se font "mot par mot". Si les mots sont deux fois plus grands, il y en a deux fois moins et donc ca prend deux fois moins de temps. Mais c'est une situation un peu extrême.

Faut-il en tenir compte? Disons que l'idéal est d'exploiter les 64 bits des variables sinon on ne voit presque pas la différence. Si c'est pour représenter des entiers à 3 chiffres, la pluparts des 32 nouveaux bits sont inutiles. Par contre, on peut en profiter pour obtenir une précision accrue, ce qui peut être assez intéressant en chimie. Sur des nombres flottants, 32 bits de plus c'est agréable. Il faut en tenir compte dans la conception, mais il n'y a normalement pas une seule ligne de code à changer grâce à l'utilisation de sizeof() (je suppose que ça existe en C++...).

Après Le plus gros du travail se passe à la compilation, le programme lui-même ne doit pas être modifié (ou très peu) normalement.

est ce que pour utiliser les 2 processeurs il faut forcement etre en multi thread ?

Oui, car les processeurs se répartissent les threads du système. Si le programme n'a qu'un thread (la situation "normale"), seul un processeur travaille dessus, l'autre ou les autres s'occupent des threads d'autres programmes ou de font rien en fonction de l'activité du système.

si c'est en multithread, est ce que linux se debrouille comme un grand pour repartir les threads

Oui, pour lui il n'y a pas de différence entre deux threads d'un seul programme et deux threads de deux programmes différents.

comment verifier que tout ca marche bien ?

En tapant ps -efx, la liste des processus en cours va apparaître. Quand un programme lance plusieurs threads, il y a une filiation entre les threads : le père crée le fils. Il suffit de regarder s'il y a bien deux 'R' (pour Running) dans la colonne STAT pour s'assurer que deux processeurs travaillent. Si le système n'a pas d'autres tâches, les deux threads en cours doivent être ceux du programme qui nous intéresse, et le PPID (ID du processus père) de l'un doit avoir la même valeur que le PID (ID du processus) de l'autre.

Attention cependant que dans certains langages (Java, par exemple), les threads sont pris en charge par un processus exécutant le programme. Linux ne voit donc qu'un thread.

quelle est la question que j'oublie ?

J'en sais rien tongue

ya t il des choses a savoir pour ce genre de bidouilles ?

Ne pas créer de boucle infinie là où on crée les threads, sinon l'ordi pète vite un câble. Se demander si le programme se décompose naturellement en plusieurs threads, car si le multithreading peut améliorer sensiblement la vitesse d'exécution d'un programme (indépendemment de l'architecture utilisée), on peut avoir des performences désatrueuses si les threads doivent s'attendre sans arrêt par exemple.

Dernière modification par Lord Alembert (Le 31/07/2006, à 15:54)

Hors ligne

#3 Le 31/07/2006, à 16:03

jobherzt

Re : bi processeurs

merci pour ces reponses completes !

je me doutais un peu de tout ca. en fait, je travaille sur des doubles ou des floats. est ce qu'en 64 bits, si je passe tout en float, j'aurais mecaniquement la meme precision qu'en double sur un 32 bits ? mais du coup, ca sera plus rapide car il travaille plus vite sr des floats..

pourquoi aurait je besoin d'utiliser sizeof() ? si je n'ai pas a changer le programme par ailleurs ?

a priori, le programme se decompose assez naturellement en multi thread, et n'ont presque pas besoin de "s'attendre". en fait, on peut schematiser en disant que les threads partagent l'acces a une pile, ou ils prennent et posent du travail a faire. chaque travail peut se faire de maniere independante. le seul cas ou ca coince, est qu'il peut arriver que la pile soit vide parce qu'un thread a pris la derniere tache, mais en sachant qu'il va certainement remettre du boulot dedans donc il ne faut pas pour autant que les autres threads terminent (est ce clair :-) )

donc la solution bourrine pour l'instant c'est "tant que la pile est vide mais qu'un thread bosse, boucler en rond"... je ne sais pas quel impact ca peut avoir sur les performances...

merci encore !

Hors ligne

#4 Le 31/07/2006, à 16:38

jobherzt

Re : bi processeurs

ah : et si je tourne la question autrement : est ce que je peux, dans ma programmation, exploiter les 64 bits pour rendre le calcul plus rapide ??

Hors ligne

#5 Le 31/07/2006, à 17:43

Lord Alembert

Re : bi processeurs

Je ne peux pas garantir que le float en 64 bits a exactement la même portée que le double en 32 bits. Il faudrait tester pour voir. En farfouillant dans les fichiers de GCC, il doit y avoir moyen de tomber sur une macro indiquant les nombres les plus grands, les plus petits et le pas de résolutions des flottants et doubles pour comparer. Ou alors aller voir de la doc technique mais je ne sais pas où hmm

Le programme semble pouvoir tirer un grand avantage du multithreading. Ce que je ferais, c'est avoir un thread principal qui boucle en rond en faisant des pauses de ~1 seconde à chaque boucle.

A chaque tour, si ce thread découvre qu'il y a du travail, il crée un thread en lui indiquant le travail à faire puis termine sa boucle. S'il n'y a pas de travail, il termine aussi sa boucle.

On a ainsi, un programme où chaque travail commence au plus tard 1 seconde après son dépôt sur la pile (temps réglable, si on veut un programme plus ou moins "nerveux") et qui ne consomme pas de ressource s'il n'y a rien à faire. Et s'il y a du travail, la boucle principale ne pompe pas trop de ressources car elle passe le plus clair de son temps à dormir. Dès qu'il y a au moins deux travaux, les coeurs sont exploités de façon optimale.

Une autre solution pourrait être que l'entité qui dépose le travail sur la pile crée elle-même le thread nécessaire à l'accomplissement du travail. Il n'y a ainsi plus de pile et plus de thread dispatcher. L'ensemble est donc plus fluide, mais l'entité qui fourni le programme doit se charger elle-même du bon déroulement du travail. Une fonction ou un objet (en fonction du style de programmation utilisé) pourrait faire l'affaire.

J'avais fait allusion au sizeof car certains programmeurs exploitent les bits à leur disposition en mettant en dur int = 4 octets par exemple. Ce qui n'est évidement pas un bon plan si on change le processeur.

Pour ce qui est du gain de vitesse, il faut voir si le programme peut se satisfaire de floats en 64 bits au lieu de double en 32 bits. Si on considère que le double 32 bits était plus précis que nécessaire, je pense que le float 64 bits suffira amplement. Reste à savoir s'il y a réellement un gain de vitesse à ce niveau, et surtout si un float 64 bits peut réelleement remplacer un double 32 bits.

Dernière modification par Lord Alembert (Le 31/07/2006, à 17:45)

Hors ligne

#6 Le 31/07/2006, à 17:52

jobherzt

Re : bi processeurs

ok d'acc, merci pour ces reponses...

futé, la technique, je n'avais pas pensé a supprimer carrement la pile !! ca vaut le coup d'essayer ! mais est ce que le fait de creer un threads a un cout ?? pour l'instant, pour detailler plus, je fixe a l'avance le nombre de threads. ils font tous la meme chose, et en fait, l'algo a une "tronche" de recursif.. en single thread ca donnerait :

empiler le truc de depart
tant que la pile n'est pas vide
   depiler la pile pour prendre un element courant
   le traiter. 
   si on conclut, c'est cool
   si on n'arrive pas a conclure, on coupe le bidule courant en 2
   on empile les 2 "moitiés"
fin tant que.

en multi thread, j'ai donc un nombre fixé de threads, avec un mutex sur la pile quand je la modifie. chaque traitement est tres court.

je vais reflechir a tout ca !!

a priori, le probleme etant assez bourriin, le programme ne donne de toute facon pas un resultat tres precis, par contre il sort un encadrement. donc la priorité c'est la vitesse, pas la precision.. donc je pense que je vais passer tout ca en float !

Dernière modification par jobherzt (Le 31/07/2006, à 18:22)

Hors ligne

#7 Le 31/07/2006, à 19:53

Lord Alembert

Re : bi processeurs

Créer un thread est bien plus léger que de créer un processus. Je crois que sous UNIX on peut compter un rapport 1/1000. C'est pour cela qu'on parle de "processus léger". Il y a quand même un coût, et il vaut mieux réutiliser un thread que de le supprimer et en créer un nouveau.

Dans le même ordre d'idée, passer d'un thread à l'autre s'avère plus facile que passer d'un processus à l'autre car une bonne partie des données restent en mémoire.

Attention qu'à priori avec le mutex il risque d'y avoir pas mal d'embouteillages entre les threads. Car même s'ils ne doivent pas communiquer explicitement entre eux, le mutex bloque tous les threads qui attendent leur tour sur la pile.

Il aurait mieux valut avoir quelques tâches longues que plein de tâches très courtes, le mutex intervenant à chaque début/fin d'un thread. Enfin, on ne fait pas toujours ce que l'on veut, mais l'idée de se passer de la pile et des mutex devient assez intéressante dans ce cas.

L'idéal si on utilise une pile serait qu'un thread gère un problème complet à lui tout seul, afin de ne pas utiliser sans arrêt la pile. Plus le problème mettra longtemps à être résolu, meilleurs seront les performences si on utilise une pile. Par contre, le programme sera moins "fin" et il y a un risque plus important que vers la fin des traitements un coeur utilise un thread pendant que l'autre ne fait rien, alors qu'en décomposant plus finement le problème les deux coeurs sont utilisés jusqu'au bout.

Hors ligne

#8 Le 31/07/2006, à 19:59

jobherzt

Re : bi processeurs

bien vu, je vais penser a tout ca !!

Hors ligne