J'ai fait sur ma machine le test décrit sur kerneltap. Un mail en haut du thread donne un petit programme appelé "task2", qui affiche en continu le temps qu'il faut pour exécuter une boucle vide de 100 millions d'itérations.
Le programme "task1" est donné par le code suivant :
#include <sched.h>intmain(){while(1){sched_yield();// Version 1asm("pause");// Version 2, instruction PAUSE conseillée par Intel pour les busyloops;// Version 3, On ne fait rien}}
Seulement une des trois lignes est décommentée à la fois, pour avoir trois versions du programme. les deux programmes sont compilés en -O0, sinon GCC est trop intelligent et élimine les boucles vides. Les résultats sont les suivants (plus c'est petit, plus c'est rapide) :
Quand task2 tourne seul sur un coeur, aucune autre tâche en parallèle : 505851 plus ou moins des poussières, je vais considérer le nombre 50
Quand task2 tourne seul sur un coeur, avec sched_yield sur un autre : 52
Quand task2 tourne seul sur un coeur, avec pause sur un autre : 51
Quand task2 tourne seul sur un coeur, avec la boucle vide sur un autre : 51
Quand task2 tourne sur le même coeur que sched_yield : 76 (alors qu'idéalement, on aurait voulu 50 ou 51, l'autre tâche yield le processeur)
Quand task2 tourne sur le même coeur que pause : 150
Quand task2 tourne sur le même coeur que la boucle vide : 88
Le choix des coeur est fait avec taskset -c X commande, avec X égal à 0 ou 2, sachant que mon processeur dispose de l'hyper threading, et que les coeurs 0 et 1 sont en fait deux threads du même coeur physique. J'ai découvert ça en lançant task1 et task2 sur les coeurs 0 et 1, et les deux étaient ralenties. La fréquence de mon processeur a été fixée à 1200 Mhz pour tous les coeurs (fréquence basse car je suis sur batterie et j'aimerais éviter de consommer 35 W).
Si j'essaie de tirer des conclusions, je dirais que sched_yield induit un léger ralentissement inter-coeurs (résultat 2), sans doutes parce que le scheduler doit agir, ou que les caches sont vidés. Par contre, sched_yield semble sur ma machine (Linux 3.8.8 d'openSUSE 12.3, x86_64) la solution la plus rapide pour quand deux threads partagent le même coeur. De manière surprenante, PAUSE introduit un énorme ralentissement quand les deux tâches sont sur le même coeur !
J'ai en tous cas l'après-midi devant moi pour m'intéresser aux futex.
[^] # Re: Ai-je bien compris ?
Posté par steckdenis . En réponse au journal Performances des processeurs Intel et optimisation. Évalué à 1.
C'est en effet très intéressant !
J'ai fait sur ma machine le test décrit sur kerneltap. Un mail en haut du thread donne un petit programme appelé "task2", qui affiche en continu le temps qu'il faut pour exécuter une boucle vide de 100 millions d'itérations.
Le programme "task1" est donné par le code suivant :
Seulement une des trois lignes est décommentée à la fois, pour avoir trois versions du programme. les deux programmes sont compilés en -O0, sinon GCC est trop intelligent et élimine les boucles vides. Les résultats sont les suivants (plus c'est petit, plus c'est rapide) :
Le choix des coeur est fait avec
taskset -c X commande, avec X égal à 0 ou 2, sachant que mon processeur dispose de l'hyper threading, et que les coeurs 0 et 1 sont en fait deux threads du même coeur physique. J'ai découvert ça en lançant task1 et task2 sur les coeurs 0 et 1, et les deux étaient ralenties. La fréquence de mon processeur a été fixée à 1200 Mhz pour tous les coeurs (fréquence basse car je suis sur batterie et j'aimerais éviter de consommer 35 W).Si j'essaie de tirer des conclusions, je dirais que sched_yield induit un léger ralentissement inter-coeurs (résultat 2), sans doutes parce que le scheduler doit agir, ou que les caches sont vidés. Par contre, sched_yield semble sur ma machine (Linux 3.8.8 d'openSUSE 12.3, x86_64) la solution la plus rapide pour quand deux threads partagent le même coeur. De manière surprenante, PAUSE introduit un énorme ralentissement quand les deux tâches sont sur le même coeur !
J'ai en tous cas l'après-midi devant moi pour m'intéresser aux futex.