CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

programme pour dble coeur

saleGauss
saleGauss
Niveau 9
03 avril 2007 à 15:09:43

Bonjour,

Voila, les processeurs double coeurs sont bien présents maintenant, et je me pose quelques questions sur le manière d´exploiter cette technologie.
Comment, dans un programme C++ par exemple puis-je tirer profit du double coeur?
J´imagine qu´il faut utiliser deux processus et faire tourner les processus en parallèle sur les deux coeurs. C´est bien ca?

Concretement, coment gérer cela?

Voia, si quelqu´un possède quelques connaissance ssur le sujet, il est le bienvenue pour m´éclairer ! Merci.

sn00bino
sn00bino
Niveau 5
03 avril 2007 à 15:29:00

Faut faire des threads, j´ai un article sur la programmation sur plusieurs coeurs et les jeux video.

Il n´ empeche qu´ il faut faire attention, on ne peut pas tout threadé. Prenons un exemple débil : Moi. J´ ai la capacité de m´ habillé tout en prenant ma douche, c ´est 2 fois plus rapide mais le résulat est décevant ( quoi que defois ). C ´est pareil avec les ordinateurs :
ne les met jamais sous la douche.

saleGauss
saleGauss
Niveau 9
03 avril 2007 à 16:02:30

Merci d´avoir répondu.
Peut tu me donner l´adresse URL de ton article.
Merci

sn00bino
sn00bino
Niveau 5
03 avril 2007 à 16:24:47

il est dans la Doc directX ( une doc fantastique ). Si tu as la doc c ´est dans les Technical Articles. Sinon jpeux te faire une mini synthétisation :

Il faut faire des threads qui s´ occupent de choses bien séparé sinon il y a des attentes de synchonisation énorme, et des corruptions.

Par exemple tu ne peux pas calculer les collisions et toutes la physique dans un autre thread que celui du rendu.

Mais tu peux par exemple afficher la pluie, le ciel, les mouvements des habits... dans un autre thread.

Une autre possibilité et de faire tout le rendu dans un thread et tout les calculs dans l´ autre. Le thread de calcul devra avoir une frame d´avance. Il y aura donc une mini attente au niveau des réactions sur un low frame rate.

On peut bien sur séparé le thread du chargement du reste et ainsi faire des chargements moins longs et plus agréable.

Pour créer un thread il est conseillé d´ appelle la fonction _beginthreadex() plutot que CreateThread()
Voici comment :

const int stackSize = 65536;
HANDLE hThread = (HANDLE)_beginthreadex( 0, stackSize,
ThreadFunction, 0, 0, 0 );
// Do work on main thread here.
// Wait for child thread to complete
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread );

saleGauss
saleGauss
Niveau 9
03 avril 2007 à 16:30:01

Merci beaucoup.
Donc si je comprend bien il faut faire attention a ce que chaque thread n´attendent pas des calculs(ou autre) faits sur l´autre thread, sinon po bien.
Je vais essayer de voir tout ca plus en détail sur la doc de dx.
Je reposte si je comprend pas tout bien!
Bye

Fvirtman
Fvirtman
Niveau 10
03 avril 2007 à 16:38:01

Programmation parallele
j´ai un tuto la dessus :
(cf ma carte) §L.

godrik
godrik
Niveau 30
03 avril 2007 à 23:18:48

je devrais aussi pas tarder a vous poster un compte rendu de l´utilisation efficace des architecture multi-coeur... Bah c´est pas facil du tout, les kernels ne sont pas adapté a ca...

Sinon, il n´y a pas que lkes threads dans la vie, il y a les processus aussi...

finalement, le principal quand on fait des applications sur deux coeur, ce n´est pas d´utiliser les deux coeur, mais de les utiliser efficacement. Une branche de l´algorithmique parallele traite des algorithmes adaptatifs, c´est a dire qui s´adapte de facon dynamique a la puissance de calcul disponible sur chacune des ressources.

Fvirtman
Fvirtman
Niveau 10
04 avril 2007 à 09:39:28

Il est vrai que ça va bien au dela de la création de threads (dans mon tuto), il faut aussi protéger les acces simultanés en mémoire (avec des Mutex, pour éviter les mauvaises surprises).
Il y a aussi les multiprocessus, qui eux ne partagent pas la meme mémoire, par contre, ils peuvent communiquer par un "tuyau" de données (appellée "pipe").

Mais la vraie difficulté, comme dit Godrik, c´est de faire de la prog parallele efficace, et ça, c´est une autre paire de manches :-)
Quant aux algorithmes adaptatifs, alors la, je pense que c´est déja pour les warriors de la programmation parallele :-)

godrik
godrik
Niveau 30
04 avril 2007 à 10:32:39

Oui fvirtman, c´est quelquechose d´assez nouveau qui n´est pas encore arrivé dans les programmes universitaires. Parcontre, c´est vraiment essentiel dans la bonne utilisation des architectures paralleles. Faire un programme parallele, c´est facile. Bien le faire, c´est vraiment tres difficile. Si on ne fait pas attention, on se retrouve rapidement a etre sequentiel, cad un seul processeur travaille vraiment. Et ca c´est vraiment completement ce que l´on ne veut pas, puisque paralleliser coute cher et il FAUT rentabiliser ce cout. Ce qui n´est pas fait quand on est sequentiel.

En outre, paralleliser sur les machines dédié (je penses au console) sera plus facile que sur PC puisque l´on a toute la machine, on n´a pas a se demander si on gene d´autre processus...

Fvirtman
Fvirtman
Niveau 10
04 avril 2007 à 11:35:11

La derniere fois que j´ai utilisé le multithread, c´est pour mon aspirateur de jeuxvideo.com (chuut, faut pas le dire !)

Un programmeur qui scanne tous les jeux de jeuxvideo.com, télécharge pas mal de screenshots, et construit un minisite d´"overview" des jeux par genre et par machine.
J´ai parallelisé les téchargements, chaque thread pompe un jeu (donc ses screenshots), avec son propre port. Pour le réseau, c´est utile :)

kufa
kufa
Niveau 9
04 avril 2007 à 14:28:51

En outre, paralleliser sur les machines dédié (je penses au console) sera plus facile que sur PC puisque l´on a toute la machine, on n´a pas a se demander si on gene d´autre processus...

Si seulement c´etait vrai..
Les consoles next-gen ont un OS qui va avoir ses propres threads qui tournent en meme temps, que l´on peut plus ou moins scheduler sur un Logical Processor selon la console, par exemple les threads haute priorite des drivers sons.

Comme le dit godrik, faire un programme multithreade n´est pas trop difficile, mais faire un bon programme MT est tres difficile.
Il ne faut pas abuser du MT, les contexts switches sont tres couteux. Quelques tips pour savoir quand utiliser du MT (lorsqu´on est sur une machine multi cores):
- comme mentionne dans un post plus haut, lorsque de gros calculs sont effectues sequentiellemens sur des donnes independantes (occlusion, qq parties d´un moteur physique, cpu skinning (cf ps3), particles update, ...)
- lorsque l´on doit attendre longement pour le hardware (renderer, network (cf overlapped operations sous windows), file reader, ...)
- lorsqu´on veut avoir une thread dormante (cf triggerable de maniere globale, par exemple pour faire un crashdump lorsque il y a un deadlock)

Quelques tips sur le MT:
- utiliser les critical sections avec spinlock si possible, et surtout ne pas locker un cs trop longtemps; c´est souvent un signe de mauvais design lorsque l´on a un cs autour d´un gros bloc de code, et de maniere generale pour le MT il vaut mieux diminuer le nombre de locks quels qu´ils soient
- ne pas utiliser de valeurs globales lorsqu´on design les threads. Ca deviendra plus facile a coder (et de toute facon les valeurs/fonctions globales augmentent le physical coupling, beark)
- utiliser le mot clef volatile. Attention, volatile est juste un mot clef qui informe le compiler que lorsqu´on accede a cette valeur il faut relire la valeur (ie le compiler ne doit pas cacher la valeur sur la stack et reutiliser cette valeur, mais a la place relire la zone memoire). Selon le compilo et la platforme, cela ne garanti pas la coherence du cache. Utiliser des memory barrier via des intrinsics ou de l´inline assembleur pour garantir le cache coherency.
- Les spinlock loops du type while( m_bMonBoolean ) ; ne sont pas une bonne idee si codes comme ceci. Ajouter un _asm pause; . Les waitforsingleobject (ou multiple) sont tres utiles, mais ne sont pas des spinlock loops.
- Attention a la gestion de la memoire (new/malloc), aux outputs screens, aux profiling, etc, diminuer le plus possible ces acces la, et rendre les systemes MT-safe.
- sur pc, ne *pas* utiliser rdtsc pour l´implementation d´un timer. Utiliser les QueryPerformanceCounter/Frequency sur le *meme* core via un setthreadaffinitymask. Aussi, ne pas assumer que windows va lancer le programme sur le premier core. Ne pas forcer l´affinite d´une thread a moins que cela soit vraiment indispensable, il est tjs bcp plus judicieux de laisser windows rescheduler les threads.

/david

godrik
godrik
Niveau 30
04 avril 2007 à 21:21:01

kufa, pourrait tu detailler les points suivants ?
a propos de volatile:
"Selon le compilo et la platforme, cela ne garanti pas la coherence du cache. Utiliser des memory barrier via des intrinsics ou de l´inline assembleur pour garantir le cache coherency. "
Sais tu comment fonctionne gcc sur les core duo et les opteron ?
a propos des spinlocks
"Ajouter un _asm pause;"
Que fait il exactement. pourquoi voudrait on faire cela. Quel est le probleme de faire du polling actif sur une variable ?
A propos des performances counters:
"sur pc, ne *pas* utiliser rdtsc pour l´implementation d´un timer. Utiliser les QueryPerformanceCounter/Frequency sur le *meme* core via un setthreadaffinitymask."
Pourquoi ? rdtsc me fournit des informations synchronisé sur les machines ou je l´ai testé (octo optoron, dual core intel, hexa powerPC64)

"Ne pas forcer l´affinite d´une thread a moins que cela soit vraiment indispensable, il est tjs bcp plus judicieux de laisser windows rescheduler les threads."
C´est super dangereux, ca veut dire que tu t´expose a ce que windows te migre et ce n´est probablement pas ce que tu veux. Une algorithimique inteligente devrait te garantir que tu utilise de facon optimale tes processeurs.

J´ai en outre des questions annexes sur le fonctionnement du scheduler de windows:
est il préemptif ? Ce que je veux dire précisement. Si un thread A était en sommeil et qu´il est TRES prioritaires (genre REAL TIME), est ce que windows déschedulera le thread en cours d´exécution pour scheduler mon thread A au moment ou il deviendra disponible ou faudra t´il attendre la fin du quantum de temps alloué au thread en cours d´exécution ?
A combien est le quantum de temps maximale de windows ?
Cette valeure est elle modifiable ?
Pouvons nous changer le scheduler de windows au cas ou il ne nous plairait pas ?

kufa
kufa
Niveau 9
05 avril 2007 à 04:07:51

Pff j arrive pas a dormir, j en profite pour une reponse tardive, mais probablement remplie de fautes d orthographes. Je vais essayer de faire clair..

Sais tu comment fonctionne gcc sur les core duo et les opteron ?

Nope, no idea. Je pense que seul VS2005 (SP1?) et ICC vont mettre une memory barrier, mais a verifier. Un peu d´intrinsic/asm inline ne fait pas de mal :)

Que fait il exactement. pourquoi voudrait on faire cela. Quel est le probleme de faire du polling actif sur une variable ?

Ce n´est pas un probleme, mais ce n´est pas recommende, car non optimal. Ok, jvais essayer de faire simple.. Une loop si petite a des effets secondaires sur, par exemple, les procs intel a partir du pentium pro. Les instructions de lecture de de comparaison de cette loop sont passes en "speculative execution", ie le proc va faire du out-of-order execution (pour remplacer ensuite les instructions lue par le proc, ce qu´on appelle les retired instructions). Mais ici il y a challenge sur la memoire (et cache) pour le speculative execution et les instructions normales, donc grosso modo les instructions attendent le resultat de la precedente. Avec l´asm pause, ce n´est plus le cas, et du coup ca libere des resources pour par exemple l´hyperthreading.

Pourquoi ? rdtsc me fournit des informations synchronisé sur les machines ou je l´ai testé (octo optoron, dual core intel, hexa powerPC64)

rdtsc est vraiment qqchose a bannir pour les nouvelles platformes (et meme sur les anciennes). Explication: tout d´abord, l´instruction est prevu pour tournee en ST sur du single core. Rien ne garanti qu´un autre core utilise la meme frequence et possede la meme base de temps (je veux dire par la que si meme les frequences sont les memes, rien ne garanti que le "0" soit le meme). Ensuite, avec le power management, la frequence du processeur peut changer.. QueryPerformanceCounter/Frequency utilise peut etre cette instruction, mais aussi d´autres compteurs hardware. La frequence retourne est (depuis un patch pas si lointain que ca) fixe par core. Par contre, plus couteuses, ses operations sont a effectuer avec moderation si possible, et sur un LP fixe.

C´est super dangereux, ca veut dire que tu t´expose a ce que windows te migre et ce n´est probablement pas ce que tu veux. Une algorithimique inteligente devrait te garantir que tu utilise de facon optimale tes processeurs.

Ben si, je veux que windows me migre si possible. Explication: si tu as de grosses threads (a savoir longue duration et cpu intensive), windows va les repartir correctement sur les differents cores. Si tu as d´autres petites threads, elle vont etre reschedulee la ou il y a de la place, et ce n´est pas une mauvaise idee d´utiliser un core sur lequel tourne une grosse thread qui est en wait de sync avec une autre. Sur le game engine sur lequel je taf, ne pas fixer l affinity mask augmente entre 5% et 10% le total cpu usage.. Peut etre un exemple: dualcore, thread A (grand cpu usage), thread B (grand cpu usage), et thread C (petit cpu usage, par exemple overlapped network thread). Si on force l´affinite a A(1),B(2),C(2), et si A est en spinlock/wait avec B, C ne pourra pas etre reschedulee sur le core 1, ce qui n´est pas du tout avantageux.
Certes un design plus avance pourrait permettre de fixer les affinites, mais cela pose d´autres problemes: premierement, on ne peut pas gerer les affinity des third parties / de l´os (driver son, DX, etc), et windows va rescheduler comme il veut ces thread. Avec de la chance, ca se passe bien, mais ca ne sera pas forcement optimal si une de ces thread a aussi un affinity mask.
Ensuite, sans code un peu plus avance, ca interdit le multiple instances.
De meme, pour modifier proprement l´affinity mask d´une thread pour que cela corresponde a un core, il faut connaitre le bon mask et donc pouvoir determiner la topology du system. Ca se fait, pas triviallement par contre, et le code (rempli d´asm inline) est different sur Intel, AMD, etc
D´un point de vue design, c´est pas super propre non plus. Si la premiere passe de design se fait bien, lorsque tu veut rajouter un systeme qui cree une thread juste sur quadcores, il faut definir exactement comment cela va rentrer la dedans, et modifier si necessaire les affinity mask de partout (et connaitre celles des autres systemes)
Perso je pense que Windows fait un tres bon travail dans son scheduling, et je n´ai jamais eut de soucis.

Pour repondre a tes questions sur le multithreading sur windows:
oui le scheduler de windows est premptif. Par contre, il faut bien comprendre voir que ta thread A ne sera activee uniquement (et des) qu´une fois ce qu´elle attendait est pret, et que le scheduler est au courant. Ie faire un spinlock while(m_bool_fini) dans la thread A est une mauvaise idee, mais il faut plutot utiliser un waitforobject histoire que l´os puisse rescheduler (ou faire un sleep(0) apres avoir modifier le boolean dans l´autre thread).
Petit info complementaire: essayer d´eviter ou de limiter les high pri threads, afin d´eviter ce qu´on appele la priority inversion: imaginons qu´il y ait 3 threads, low, medium and high (pour leur priority). low acquiert un lock, high est alors reveillee et preempt low, high veut le lock, du coup medium est reveille et prempt high, et il faut attendre la fin du time quantum de medium pour que low release le lock.

A combien est le quantum de temps maximale de windows ?

Aucune idee :) j´ai en tete 10ms, mais c´est peut etre xboite ou ps3, je suis plus sur..

Cette valeure est elle modifiable ?
Pouvons nous changer le scheduler de windows au cas ou il ne nous plairait pas ?

No idea :)de
/kUfa

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment