La réalité dépasse l'affliction
J'ai découvert votre réflexion après un post indépendant sur le même sujet:
http://www.developpez.net/forums/d76...hreads-moteur/
Il me semble (c'est un constat dénué de toute forme d'agressivité) que plusieurs confusions, ou plutôt conséquences des intoxications d'un marketing astucieux, sont à l'œuvre dans de nombreux posts:
Si la théorie permet d'échafauder une "vision" mutithread physique des "nouveaux" µp (je ne parle pas pour le moment des coprocesseurs graphiques) le pragmatisme voudrait que l'on vérifie en situation les gains réels en performances et, s'il y en a, mettre en évidence les lieux réels de ses gains. Pour faire simple, "Un µp tient, vaut mieux que deux threads tu l'auras" :lol:.
A lire plusieurs, il semblerait que déterminer sois même les cœurs utilisés, l'affinité des threads et "blinder" les niveaux de priorités avec, par exemple, les API bien connues:
AvSetMmThreadCharacteristics
SetProcessAffinityMask
SetThreadPriority
SetThreadAffinityMask
suffise à augmenter les performances en partageant un travail qui serait sagement parallélisé à notre convenance :?.
Je suis hélas désolé d'avoir à le dire:
Ce n'est absolument pas vrai, ni vérifié en pratique. Toutes les mesures indiquant le contraire.
En un mot, plus direct: "C'est totalement faux." :oops:
Je m'explique:
Les fondeurs savent que les codeurs ne connaissent pas grand chose (rien d'agressif dans leurs constatations) aux mécanismes qu'ils mettent en place et ne souhaitent donc pas voir leurs productions dénigrées simplement parce que le code n'est pas performant.
Leurs technologies sont donc prévues pour être les plus libres possible (indépendantes) de la qualité du code (ne tombons pas dans la caricature, je n'ai pas dis "totalement" indépendant, ce serait me faire un vilain procès :mouarf:).
Donc, moins le code interfère avec une architecture bien conçue, plus il a de chances de tourner efficacement.
En français courant: Chacun son boulot et les vaches seront bien gardée, "vaches" étant mis pour performances, évidemment.
Pourquoi ne pas pratiquer des benchmarks pragmatiques:
Temps réellement passé dans chaque thread par rapport au temps global d'utilisation du µp.
Cela permet des mesures prenant en compte les changements de contextes et les générations des nouvelles interruptions que vous avez décidé de générer de manière unilatérale (sans laisser faire le µp).
J'ai bien peur (en fait, soyons clair: "Je suis sûr de mes affirmations") que les comparaisons multihread µp VS multithread organisé via code présenteront immanquablement le même constat:
Le µp gère ça bien mieux que mon code… :calim2:
Le µp sait "démonter" et "remonter" des commandes issues d'un même bloc de code ; la vision par thread étant une vision de codeur et non d'électronicien, le µp n'a de profondeur (d'ensemble) de vue que l'instruction suivante, précédente et leur liens contextuels.
Les diverses informations des constructeurs, qui tiennent plus de la vulgarisation que du transfert de technologie (ne soyons pas irréalistes :mouarf:) présentent souvent les choses sous une forme graphique qui ne précise pas si la gestion des threads est sous le control du codeur ou de l'exécuteur (l'électronique)…
Le but étant de montrer que le multiplexage se fait au niveau temporel et non plus au niveau des tâches proprement dites et qu'il y a un gain mesuré en échelle de temps (c'est bien là l'astuce marketing 8O).
Tout ce que nous vivons et ressentons se mesure en échelle de temps constant: Une courbe de fonction, les sens (variations d'intensités dans le temps) etc. Donc, faire varier le temps dynamiquement reviendrait à modifier la courbe de perception.
Tant que le temps reste à granulation constante, nous arrivons à maintenir cohérents nos raisonnements de codeurs.
Avec une granulation temporelle dynamiquement variable, ces raisonnements montrent leurs limites dans le domaine qui n'est plus le leur:
La logique programmée.
Les logiques câblées ou locales étant forcément plus rapides que les logiques programmées ou distantes, les gains seront donc obtenus en favorisant les opérations les plus locales et les moins contextuelles possible.
Cette stratégie est celle de tous les µp depuis maintenant plusieurs décennies et la multiplication des cœurs ne change rien à celle-ci. Ne pas s'y conformer n'apportera que des pertes et en aucun cas des gains.
Le rôle du codeur étant de générer la stratégie la plus proche de celle utilisée par sa cible électronique et non pas de parier sur une forme de vue de l'esprit sans aucun rapport avec le pour "qui" il code.
Pour résumer:
- Vous codez pour une électronique conciliante, certes, mais pas dénuée d'orientation et de performances liées à celle-ci.
Il est donc primordial de favoriser l'orientation par rapport à la conciliation: Ne pas chercher à tirer l'électronique vers le code mais bien plutôt de faire le contraire en appuyant ce dernier pleinement sur elle.
- Les threads sont une vue de l'esprit pour le compilateur et non une réalité pour le µp.
- Vous obtiendrez de bien meilleurs résultats en repensant votre stratégie et votre architecture globales, comme cela à été souligné brièvement par plusieurs dans ce topic, cad en désolidarisant "totalement" les tâches les unes des autres et en les rendant non bloquantes.
- Tous les coprocesseurs (sauf cette stupide FPU) sont fondés sur ce principe. Ils sont les réelles threads physiques de votre plate-forme cible.
- Une vision plus matérielle permet de mieux saisir que la mise en parallèle de sérialisations est la bonne méthode: Lancer des séries process hardware réels en même temps. Le hardware possédant, la plupart du temps, une file d'attente vidangeable (cas des GPU, cartes audio, µp…).
Je vous renvoie à l'autre post cité en entête pour un exemple parmi tant d'autres.