> Par contre, ce qui est très très gonflant c'est les applis gnome qui utilisent gconf, qui font que pour le moindre truc à configurer tu es obligé de passer par gconf là où une bête popup et 2 boutons suffirait...
Rien à voir avec Gconf, c'est un choix d'UI de Gnome.
Il doit bien y avoir des options dans KDE qui ne sont disponibles qu'en bidouille des fichiers .ini. C'est la même chose pour Gnome, sauf qu'on ne bidouille pas des fichiers, on utilise Gconf.
> Chez moi, ils sont pas disséminés, mais tous dans ~/.config
Ça m'étonnerais...
GConf normalise les fichiers de configuration. Lance "gconf-editor" pour te faire une idée.
> Ça, ça peut se faire avec fam/gamin, pas la peine de sortir l'artillerie lourde...
Ce n'est pas la même chose.
GConf peut surveiller par clée par exemple. Inotify, c'est par fichier.
Si ce mécanisme de GConf est de l'"artillerie lourde", alors Gamin l'est tout autant (en plus il faut ajouter Inotify côté noyau).
Autre problème que ne gère pas Gamin, il ne sait pas si la modification est terminée. Donc si une opération de modification de Gconf demande deux écritures du fichier, t'es dans la merde...
Enfin, gconf est un serveur un peu comme un serveur de base de donnée. Il supporte les accès parallèles en lecture/écriture aux fichiers gconf en toute sécurité (rien à voir avec les fichiers .ini).
Faut vraiment rien y connaitre de gconf pour le critiquer.
Gconf c'est bien.
Je ne connais pas les détails de l'affaire. Mais si les dev Linux ont fait le choix de ne pas activer le "windows scaling" par défaut, il y a une bonne raison à ça. Ce n'est définitivement pas par envie de faire chier l'utilisateur gratuitement.
Parfois qu'on ça "ne marche pas", c'est une fonctionnalité. ActiveX ne marche pas avec Firefox, c'est une fonctionnalité.
J'ai bien dit que ça dépendait du compilateur (et hardware).
Le C ne garantit l'atomicité que pour l'accès et l'écriture (et pas pour tous les types, il n'y a que le type int qui est garantit je crois). Il (la spec du C) ne garantit pas que --n est thread safe.
> Je t'invite a faire le test sur un quadri proc, et tu verras que --n ou ++n n'est pas forcément atomique.
Déja fait.
Je ne suis pas un spécialiste en assembleur, mais je ne crois pas que les choses soit aussi simple que tu le dis.
Exemple (pour faire hypra court):
volatile int i = 0 ; ; ; ; // volatile ou non
Thread/cpu 1 : while(true) ++i ;
Thread/cpu 2 : while(true) --i ;
Les performances seront assez mauvaise car les caches des cpus ne seront pas utilisés.
Il y a des mécanismes, dont je ne comprend rien, pour que tous les cpu voit la même mémoire. Si une partie de la mémoire centrale est en cache du cpu 1 et cpu 2 veut lire cette partie mémoire, le cache de cpu 1 est invalidé.
Ceci n'existe pas pour tous les hardwares, mais c'est maintenant assez commun.
Tes instructions assembleurs sous-entendent qu'il n'y a pas d'instruction pour incrémenter directement une adresse mémoire (et donc qu'un cpu puisse dire "coucou, j'utilise cette adresse mémoire"). Je n'en suis pas convaincu.
J'attend avec délice que pBpG dise que le besoin d'un anti-virus sur un OS est la preuve d'un OS mal foutu et non de sa popularité.
Un mec de chez MS a dit que peut-être les prochaines versions de Windows ne nécessiterons pas d'anti-virus (comme Linux). Ce jour la, pBpG sera dans la merde. Enfin, pas vraiment dans la merde. Il dira la même chose que MS.
> La GPL est contaminante tout comme de nombreuses licences propriétaires.
Sauf qu'aucune licence n'a jamais rien contaminé.
Tu peux dire contaminant pour plein plein de truc alors. Dès que deux (ou plus) accords sont incompatibles, les protocoles incompatibles, etc...
Dit incompatible au-lieu de reprendre du FUD du bureau de communcation de MS.
> Le FUD de Microsoft n'est pas l'utilisation du terme "contaminant"
Viral. Ce n'est pas mieux ni pire.
> mais le fait de ne pas dire que c'est le cas de la majorité des licence
Non et je m'en fous.
Dis que la BSD est compatible avec plus de licences que la GPL si c'est ce que tu veux dire.
Mais, par exemple, être compatible avec les brevets, autoriser les accords type MS/Novell, ne plus avoir la garantit d'accès aux sources, etc ce sont des types de compatibilité que je préfère éviter.
Certaines versions de BSD ne sont pas compatibles avec la GPL. Donc, selon ta terminologie, elles sont "contaminantes".
Il n'y a pas de "contaminant" ou "viral", il y a compatible ou non. Si les licences sont compatibles, tu peux mélanger le code. Si elles ne le sont pas, il faut que tu change la licence d'un code. ET PAS FORCÉMENT PASSER LE CODE SOUS GPL ! Tu peux aussi passer ce qui est sous GPL dans la licence de l'autre.
Mais comme d'hab, vous êtes toujours dans le même scénarios. J'ai un truc (avec tous les droits) sous une licence incompatible avec la GPL et je veux incorporer du GPL.
Prend le problème dans l'autre sens :
- J'ai mon code (avec tous les droits) sous GPL et je veux incorporer du code sous une licence incompatible avec la GPL. Ben dans ce cas, t'es "obligé" d'abandonné la GPL pour prendre l'autre licence.
Les problèmes sont parfaitement symétrique et donc je ne comprend pas cet acharnement grotesque sur la GPL.
En passant, volatile marche aussi pour ce qui est pointé (c'est un usage important). Mais si j'ai bonne mémoire, la norme garantit que ça marche que pour un int (int *).
> La mise en attente demande un context switch entre autre.
Ce qui ne coûte rien (ou n'impacte pas les performances) puisque le cpu n'a rien d'autre à foutre (cas où il y a plus de cpu que de thread actif).
> (d'autant que ton code est pas thread safe, vu que deux personne peuvent rentrer avec ton ++i==1.
Il est thread-safe. J'utilise "volatile". Il est thread-safe à un petit soucis près, ça dépend du compilo et du hardware. Mais sur un PC "classique", ça marche.
> Il faut que le test_and_set soit atomique pour que ce soit viable, ce que fait l'instruction asm)
Relis bien le code. Ça marche. Ce qui compte, c'est que ++i soit atomique et réalisé par un thread à la fois (ce que nous garantit "volatile").
volatile int i = 0 ;
lock() {
while (true) {
while (i) ;
if (++i == 1) { [1]
break ;
}
else {
// lock déjà pris par un autre
--i ;
}
}
}
Thread 1 fait "++i" et obtient la valeur 1.
Thread 2 fait "++i" et obtient la valeur 2.
Thead 1 compare la valeur de retour de "++i" avec "1" beaucoup plus tard. C'est true, donc il a le lock.
Thead 2 compare la valeur de retour de "++i" avec "1". C'est false, donc il n'a pas le lock. Plus loins il fait un "--i" pour "remettre de l'ordre".
Que l'incrémentation ET la comparaison ne soit pas atomique n'est pas un problème ici. Le "volatile" garantit qu'il n'y a qu'un thread qui accède à i à la fois.
Mais il faut l'utiliser avec beaucoup de précaution.
Pour "++i" ça doit marcher.
Pour :
i = (DoLock == true ? i+1 : i ) ;
ça doit très probablement ne pas marcher. Le résultat de "i+1" peut être mis dans une "variable temporaire" puis copié dans i.
Mon lock ne marcherait pas s'il fait :
if (i==0) { ++i ; }
Mais ce n'est pas ce qu'il fait.
Il y a effectivement des instructions asm pour faire une incrémentation et un test de façon atomique (il y en a plusieurs).
> D'ailleur c'est pas pour rien que les mutex pthread sont en partie écrit en asm : pour avoir le moins d'overhead possible
Les mutex phtread, ne font pas que ce que je fais (avec la fonction lock()). Il y a spinlock pour un nombre de cycle limité, il y a vérification si c'est un système smp ou non (si c'est mono-cpu, inutile de faire le spinlock et il faut passer directement en sommeil), il enregistre l'id du thread qui fait le lock pour donner un warning si le thread qui fait l'unlock n'est pas le même, les mutex phtread sont inter-processus, mon lock() ne l'ai pas, etc...
> C'est tres simple d'avoir plus d'un million de lock par seconde.
Dans ce cas j'ai envis de dire que c'est compliqué pour ne pas faire ce million de lock par seconde.
Avec volatile (et du matos correcte), il y a plein de cas où on peut éviter les locks. Et ça marche, je le fais courrament sur des trucs qui tourne 24h/24. Par contre, je le fait avec beaucoup de précaution et uniquement pour int, long et pointeur. Il y a même des systèmes (nombreux) qui n'ont pas besoin de "volatile" :-) Les cpus/cache vérifient tout.
> Mais pas d'accord pour les sémaphores. Il est courant dans les algos de les utiliser comme des compteurs de ressources dans des cadres producteur/consomateur, et dans ce cas le thread qui fait un P() n'est généralement pas celui qui a fait un V().
Pas d'accord. C'est généralement le même thread qui fait un GetSemephore (ou équivalent en fonction de l'api) et un ReleaseSemaphore. Forcément.
Le thread prend/demande la ressource, il fait GetSemaphore. Il libère la ressource, il fait ReleaseSemaphore. Il n'y a que le thread qui sait quand il n'a plus besoin de la ressource.
> D'accord pour les mutexs, qui protègent des éléments de possibles accès concurrents
Par forcément.
- Thread 1 prend un lock et lance Thread 2 qui fait le traitement.
- plus tard Thread 1 demande encore le lock mais ne l'obtient que lorsque Thead 2 l'a libéré (une fois qu'il a fini son traitement).
Tu peux avoir la même chose avec un semaphore. Mais un semaphore c'est surtout pour des ressources, pour signaler que tu utilises une ressource. Tu peux utiliser un lock (en général 2) pour synchroniser des threads (et non seulement que protéger des données). Mais en général, c'est à éviter (il est plus clean d'utiliser les signaux ou event). Mais les locks sont extrêmement rapides.
Il faut bien distinguer deux choses :
1) L'auteur du programme _choisit_ d'utiliser du code sous licence GPL.
2) Ce choix implique _l'obligation_ de passer le programme sous licence GPL.
Le choix de l'étape 1) fait que le code sous GPL impose un changement au programme complet : un passage sous licence GPL. Donc de ce choix résulte une contamination du programme par le code sous GPL.
Il faut bien distinguer deux choses :
1) L'auteur du programme _choisit_ d'utiliser du code sous licence proprio.
2) Ce choix implique _l'obligation_ de passer le programme sous licence proprio.
Le choix de l'étape 1) fait que le code sous licence propriétaire impose un changement au programme complet : un passage sous licence proprio. Donc de ce choix résulte une contamination du programme par le code sous licence proprio.
Dans le cas de l'écriture d'un programme, avant de choisir d'intégrer un code, il est nécéssaire de lire sa licence et d'accepter toutes les conséquences. Donc si le code est sous GPL, il est nécéssaire d'accepter de modifier la licence de son logiciel. Le code sous GPL contamine donc bien le logiciel hôte puisqu'il modifie une de ses caractéristiques.
Dans le cas de l'écriture d'un programme, avant de choisir d'intégrer un code, il est nécéssaire de lire sa licence et d'accepter toutes les conséquences. Donc si le code est sous licence proprio, il est nécéssaire d'accepter de modifier la licence de son logiciel. Le code sous licence proprio contamine donc bien le logiciel hôte puisqu'il modifie une de ses caractéristiques.
Donc à mon avis le terme contaminant est tout à fait applicable et représente bien ce qui ce passe lors de l'inclusion de code sous GPL dans un autre programme.
Donc à mon avis le terme contaminant est tout à fait applicable et représente bien ce qui ce passe lors de l'inclusion de code sous licence proprio dans un autre programme.
CQFD, la GPL n'est en rien plus contaminante que du proprio (si jamais elle est contaminante).
Réfléchissez du point de vu de la GPL et du point de vu d'une autre licence. Et dans ce cas on constate que la GPL n'a rien de contaminant.
> Comment diffuser mon code ? Obligatoirement en GPL, puisque sa licence se retrouve imposée du fait de sa cohabitation avec le code importé. J'ai donc été contaminé.
Comment diffuser mon code ? Obligatoirement en proprio, puisque sa licence se retrouve imposée du fait de sa cohabitation avec le code importé. J'ai donc été contaminé.
Si la GPL est contaminance, le proprio aussi.
LA GPL N'EST PAS CONTAMINANTE !!!!
ARRÊTEZ AVEC CE FUD DE MS !!!!
Sous triple licence comme dit windu.2b.
M'enfin, la GPL a contaminé toutes les autres licences, donc Mozilla est que sous GPL. Du moins si je comprend bien la substance des propros de MS sur la GPL.
Tu devrais dire à MS que Mozilla fait du code sous GPL. Ça fait désordre de voir Mozilla/Firefox/Thunderbird sur la homepage "opensource" de MS.
Et dit à MS de faire attention s'ils bossent avec Mozilla/Firefox/Thunderbird. En effet selon MS, la GPL est virale. Ça serait con que MS-Office ou Vista se retrouve sous GPL à l'insu de son plein grés.
On a le droit de ne pas y croire, voire d'en rire.
En tout cas, si hier ils étaient sincère (n'est-ce pas pBpG ?), ils ne le sont pas aujourd'hui. Ou l'inverse.
Hier selon MS l'opensource était de la merde, une menace de l'informatique, un truc dangereux et plein de trous de sécurité, sans innovation ni avenir, etc...
Et aujourd'hui ? Ben je préfère ne pas poser la question à MS.
> Par contre le mutex te bouffe toujours meme si tu as moins de thread que de cpu : c'est une demande de synchro, il y a donc du code, un test_and_set ,
C'est ridicule, c'est fait en une centaine de cycle cpu maxi. A moins d'avoir plus d'un millions de lock par seconde, ce n'est pas un problème de performance.
> voir une mise en attente si la ressource est indisponible.
Mise en attente qui ne coûte rien puisque le thread n'a rien d'autre à faire.
Si tu ne veux pas de "contexte switch", tu peux remplacer les locks fournit par le système avec un truc dans ce goût :
volatile int i = 0 ;
lock() {
while (true) {
while (i) ;
if (++i == 1) {
break ;
}
else {
// lock déjà pris par un autre
--i ;
}
}
unlock() {
--i ;
}
Ça doit marcher mais tu ne vas pratiquement rien gagner en performance :-(. Si tu as plus de cpu que de thread, tu ne perds pas en performance. Mais si tu as moins de cpu que de thread, tu vas perdre énormément en performance puisque des cpu seront utilisés à faire des "while(i) ;" alors qu'il pourrait faire des trucs vraiment utile.
Donc les locks (mutex, critical section sous windows) ne coûte pratiquement rien et sont très très utiles.
> Non. Je te donne le cas d'un processus unique qui pouvait aléatoirement être migré entre un coeur et l'autre.
Ce qui est normal. Et ce n'est pas vraiment aléatoire. Fais des setaffinity sur plusieurs programme et tu va voir que les performances vont dramatiquement chuter. Donc déplacer un thread est tout à fait normal. Et c'est peu coûteux. Si tu veux te convaincre que c'est peut couteux, fais un "make -j nb_cpu+2" et un "make -j nb_cpu". Les deux vont s'éxécuter quasiment aussi vite. Pourtant pour le premier il y aura beaucoup plus de "déplacement" de thread d'un cpu à un autre.
Considère ça :
cpu_1 : thread_A
cpu_2 : thread_B
Thread_A passe en sommeil et thread_C est lancé sur cpu_1 (puisqu'il est disponible)
cpu_1 : thread_C
cpu_2 : thread_B
Thread_B passe en sommeil.
Maintenant le thread_A doit être lancé. Que doit faire l'OS ? Arrêter thread_C, le passer sur cpu_2, le lancer, et lancer thread_A sur cpu_1 ? Ça c'est beaucoup plus coûteux que de lancer thread_A sur cpu_2.
> Il y a quelques générations du noyau de cela, c'était même un ping pong permanent (et très coûteux).
Ce n'est pas coûteux du côté OS. Ça bouffe quasiment autant de cycle. Le problème est qu'il peut y avoir une mauvaise utilisation du cache cpu. Le problème peut être "dramatique" pour certaine architecture. Mais pas sur PC.
S'il est possible qu'un thread s'éxécute sur le même cpu, tant mieux. Mais ne chercher que ça ferait chuter les performances (et gravement).
> J'ai déjà eu le cas d'un processus (pas d'un thread, nous sommes bien d'accord) qui était migré d'un coeur à un autre
Ce n'est pas très claire. Un processus n'est pas un thread, c'est un environnement (mémoire, variable d'environnement, etc). Un processus a par défaut un thread (celui qui excécute main()). Un processus n'est pas attaché à un cpu pour la bonne raison qu'un processus peut avoir plusieurs threads.
Par exemple :
processus : toto avec 2 thread.
thread 1 de toto : s'exécute sur le premier cpu
thread 2 de toto : s'exécute sur le second cpu
A quel cpu est attaché le processus ? Aucun.
Sous linux aussi a chaque processus il y a au minimum un thread.
Exemple :
[admin@one rsync]$ ls -d /proc/5551
/proc/5551 // processus 5551
[admin@one rsync]$ ls /proc/5551/task/
5551 // thread 5551
C'est un processus (non multi-thread) qui n'a qu'un thread (il doit obligatoirement en avoir au moins un).
La différence avec Windows est que les numéros de processus et de thread son partagé. Sous Linux le numéro du premier thread d'un processus est égale au numéro du processus.
> l'ordonnanceur l'avait décidé (tu comprends, un coeur travaillait à 100%, pas l'autre, alors forcément, l'ordonnanceur a voulu donner du boulot à ce dernier ...).
Tout est normal, l'OS est là pour utiliser au mieux les ressources. Si deux thread sont attachés à un même cpu et qu'un cpu ne fout rien, l'OS va attacher un thread à un autre cpu.
En fait, on ne peut avoir deux threads sur un même cpu. Un thread est réveillé que s'il y a un cpu de disponible. Tout se faire, l'OS peut décider de mettre en sommeil un autre thread (afin de libérer un cpu).
Notons qu'un thread en sommeil n'est pas attaché à un cpu. Donc lorsque l'OS le réveille il peut l'attacher à n'importe quel cpu. Ça ne fait pas plus de boulot pour l'OS. Mais il vaut mieux le rattacher au cpu où il s'exécutait avant car le cache du cpu a peut-être des données que le thread va utiliser.
> mais bien évidemment, c'est plus ou moins indépendant du fait qu'on manipule un mutex ou non.
Pas vraiment. Tant que le thread est actif, il ne change pas de cpu. Mais dès qu'il est en sommeil il peut changer de cpu. Qu'il possède un lock ou soit en attende d'un lock n'y change rien.
Le thread peut passer en sommeil pour différentes raisons :
- l'ordonnanceur estime qu'il a écoulé son quantum de cpu et donc le passe en sommeil pour donner du cpu à un autre thread.
- le thread est passé en sommeil car il attend un lock, un semaphore, la lecture d'un fichier, etc... L'OS peut le changer de cpu au prochain réveil.
Changer de cpu un thread coûte peu. Il peut y avoir des problèmes d'utilisation du cache du cpu.
Exemple : j'ai trois threads mais 2 seulements s'exécute en même temps. Lorsqu'un thread tourne, il le fait pour très très peu de temps.
Imaginons que j'ai thread_A thread_B thread_C et deux cpu : cpu_1 cpu_2.
On peut avoir ce cas :
cpu_1 : thread_A
cpu_2 : thread_B
// thread_A passe en sommeil et thread_C est réveillé
cpu_1 : thread_C
cpu_2 : thread_B
// thread_B passe en sommeil et thread_A est réveillé
cpu_1 : thread_C // le cache de cpu_1a peut-être des données de thread_A
cpu_2 : thread_A
etc...
Les threads n'arrêtent pas de passer de cpu_1 à cpu_2 et vice versa. Le cache des cpu est mal utilisé.
Oui. C'est pour ça que j'ai dit "Au niveau appli/programmation" et non performance.
Coder pour tenir compte de la proximité des cpu/core est exceptionnel. Je ne l'ai jamais fait, je ne le ferais sans doute jamais.
Je crois que le noyau Linux affecte les cpu/core au thread en tenant compte de la "proximité" (il ne le fait peut-être que sur certains matos). Mais je ne sais pas du tout ce qui est fait, comment c'est déterminé, etc...
Il y a bien setaffinity() mais ça ne doit être réservé qu'à une appli. Si d'autres applis le font de façon intépendante, c'est une catastrophe en performance. Donc pour moi c'est à éviter.
> De ce que j'avais compris, l'utilisation de mutex te soumet potentiellement à un changement de contexte, quel que soit le nombre de processeurs actif. Je peux me tromper bien sûr.
"Te soumet potentiellement à un changement de contexte" est vrai.
Mais dans quel cas ?
Il y a changement de contexte s'il n'y a pas assez de cpu (le cpu est alors affecté à un autre thread qui en a besoin). On est dans le cas où il n'y a moins de cpu que de threads actifs/éligibles et au-lieu de laisser un cpu en attende d'un lock, on l'affecte à un autre thread.
Il y a aussi changement de contexte si le thread reste longtemps (c'est très court :-)) en attente du lock. Dans ce cas le thread passe en sommeil et sera réveillé plus tard. On est dans le cas où il n'y a rien à faire pour ce thread/cpu. On ne manque pas de cpu (en nombre, pas forcément en puissance puisqu'on peut attendre le traitement d'un autre cpu). Dans ce cas passer le thread en mode sommeil (et probablement le cpu qui l'exécutait) permet d'économiser de l'énergie. Ceci sans que les performances en souffre ou alors que très faiblement. Le thread qui était en attente (et n'avait rien à faire) sera réveillé un peu moins vite.
Il faut noter qu'on peut faire typiquement des milliers de lock à la second dans une appli multi-threadé. En général il n'y a qu'un faible pourcentage de ces locks qui demande un changement de contexte (si on a un nombre de cpu adapté à l'appli).
Plus techniquement (mais en très simplifié) un mutex fait en premier :
while (!ma_condition && ++compteur < boucle_attente) ;
Si le thread/cpu sort de la boucle et que ma_condition est vrai, il continue, sinon il passe en sommeil et l'OS le réveillera lorsque ma_condition devient vrai.
[^] # Re: ca fait peur...
Posté par IsNotGood . En réponse au journal Sortie de Gconf-Cleaner 0.0.3. Évalué à 4.
Rien à voir avec Gconf, c'est un choix d'UI de Gnome.
Il doit bien y avoir des options dans KDE qui ne sont disponibles qu'en bidouille des fichiers .ini. C'est la même chose pour Gnome, sauf qu'on ne bidouille pas des fichiers, on utilise Gconf.
[^] # Re: ca fait peur...
Posté par IsNotGood . En réponse au journal Sortie de Gconf-Cleaner 0.0.3. Évalué à 1.
Ça m'étonnerais...
GConf normalise les fichiers de configuration. Lance "gconf-editor" pour te faire une idée.
> Ça, ça peut se faire avec fam/gamin, pas la peine de sortir l'artillerie lourde...
Ce n'est pas la même chose.
GConf peut surveiller par clée par exemple. Inotify, c'est par fichier.
Si ce mécanisme de GConf est de l'"artillerie lourde", alors Gamin l'est tout autant (en plus il faut ajouter Inotify côté noyau).
Autre problème que ne gère pas Gamin, il ne sait pas si la modification est terminée. Donc si une opération de modification de Gconf demande deux écritures du fichier, t'es dans la merde...
Enfin, gconf est un serveur un peu comme un serveur de base de donnée. Il supporte les accès parallèles en lecture/écriture aux fichiers gconf en toute sécurité (rien à voir avec les fichiers .ini).
Faut vraiment rien y connaitre de gconf pour le critiquer.
Gconf c'est bien.
# Re:
Posté par IsNotGood . En réponse au journal Linus Torvalds est passé à la télé. Évalué à -3.
Ça ne serait pas :
- la photo de notre chère Linus est apparut au milieu d'anonymes.
# Re:
Posté par IsNotGood . En réponse au journal Problèmes de window scaling ? Quelle est la meilleure solution face à cela ?. Évalué à 1.
Je ne connais pas les détails de l'affaire. Mais si les dev Linux ont fait le choix de ne pas activer le "windows scaling" par défaut, il y a une bonne raison à ça. Ce n'est définitivement pas par envie de faire chier l'utilisateur gratuitement.
Parfois qu'on ça "ne marche pas", c'est une fonctionnalité. ActiveX ne marche pas avec Firefox, c'est une fonctionnalité.
[^] # Re: ouaip
Posté par IsNotGood . En réponse au journal 7 ans. Évalué à -1.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
J'ai bien dit que ça dépendait du compilateur (et hardware).
Le C ne garantit l'atomicité que pour l'accès et l'écriture (et pas pour tous les types, il n'y a que le type int qui est garantit je crois). Il (la spec du C) ne garantit pas que --n est thread safe.
> Je t'invite a faire le test sur un quadri proc, et tu verras que --n ou ++n n'est pas forcément atomique.
Déja fait.
Je ne suis pas un spécialiste en assembleur, mais je ne crois pas que les choses soit aussi simple que tu le dis.
Exemple (pour faire hypra court):
volatile int i = 0 ; ; ; ; // volatile ou non
Thread/cpu 1 : while(true) ++i ;
Thread/cpu 2 : while(true) --i ;
Les performances seront assez mauvaise car les caches des cpus ne seront pas utilisés.
Il y a des mécanismes, dont je ne comprend rien, pour que tous les cpu voit la même mémoire. Si une partie de la mémoire centrale est en cache du cpu 1 et cpu 2 veut lire cette partie mémoire, le cache de cpu 1 est invalidé.
Ceci n'existe pas pour tous les hardwares, mais c'est maintenant assez commun.
Tes instructions assembleurs sous-entendent qu'il n'y a pas d'instruction pour incrémenter directement une adresse mémoire (et donc qu'un cpu puisse dire "coucou, j'utilise cette adresse mémoire"). Je n'en suis pas convaincu.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
Un mec de chez MS a dit que peut-être les prochaines versions de Windows ne nécessiterons pas d'anti-virus (comme Linux). Ce jour la, pBpG sera dans la merde. Enfin, pas vraiment dans la merde. Il dira la même chose que MS.
[^] # Re: Alors ca c'est du bon
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 0.
Sauf qu'aucune licence n'a jamais rien contaminé.
Tu peux dire contaminant pour plein plein de truc alors. Dès que deux (ou plus) accords sont incompatibles, les protocoles incompatibles, etc...
Dit incompatible au-lieu de reprendre du FUD du bureau de communcation de MS.
> Le FUD de Microsoft n'est pas l'utilisation du terme "contaminant"
Viral. Ce n'est pas mieux ni pire.
> mais le fait de ne pas dire que c'est le cas de la majorité des licence
Aucune licence n'est contaminante. Fin.
[^] # Re: Alors ca c'est du bon
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
Non et je m'en fous.
Dis que la BSD est compatible avec plus de licences que la GPL si c'est ce que tu veux dire.
Mais, par exemple, être compatible avec les brevets, autoriser les accords type MS/Novell, ne plus avoir la garantit d'accès aux sources, etc ce sont des types de compatibilité que je préfère éviter.
[^] # Re: Alors ca c'est du bon
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 2.
Il n'y a pas de "contaminant" ou "viral", il y a compatible ou non. Si les licences sont compatibles, tu peux mélanger le code. Si elles ne le sont pas, il faut que tu change la licence d'un code. ET PAS FORCÉMENT PASSER LE CODE SOUS GPL ! Tu peux aussi passer ce qui est sous GPL dans la licence de l'autre.
Mais comme d'hab, vous êtes toujours dans le même scénarios. J'ai un truc (avec tous les droits) sous une licence incompatible avec la GPL et je veux incorporer du GPL.
Prend le problème dans l'autre sens :
- J'ai mon code (avec tous les droits) sous GPL et je veux incorporer du code sous une licence incompatible avec la GPL. Ben dans ce cas, t'es "obligé" d'abandonné la GPL pour prendre l'autre licence.
Les problèmes sont parfaitement symétrique et donc je ne comprend pas cet acharnement grotesque sur la GPL.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
Ce qui ne coûte rien (ou n'impacte pas les performances) puisque le cpu n'a rien d'autre à foutre (cas où il y a plus de cpu que de thread actif).
> (d'autant que ton code est pas thread safe, vu que deux personne peuvent rentrer avec ton ++i==1.
Il est thread-safe. J'utilise "volatile". Il est thread-safe à un petit soucis près, ça dépend du compilo et du hardware. Mais sur un PC "classique", ça marche.
> Il faut que le test_and_set soit atomique pour que ce soit viable, ce que fait l'instruction asm)
Relis bien le code. Ça marche. Ce qui compte, c'est que ++i soit atomique et réalisé par un thread à la fois (ce que nous garantit "volatile").
volatile int i = 0 ;
lock() {
while (true) {
while (i) ;
if (++i == 1) { [1]
break ;
}
else {
// lock déjà pris par un autre
--i ;
}
}
}
Thread 1 fait "++i" et obtient la valeur 1.
Thread 2 fait "++i" et obtient la valeur 2.
Thead 1 compare la valeur de retour de "++i" avec "1" beaucoup plus tard. C'est true, donc il a le lock.
Thead 2 compare la valeur de retour de "++i" avec "1". C'est false, donc il n'a pas le lock. Plus loins il fait un "--i" pour "remettre de l'ordre".
Que l'incrémentation ET la comparaison ne soit pas atomique n'est pas un problème ici. Le "volatile" garantit qu'il n'y a qu'un thread qui accède à i à la fois.
Mais il faut l'utiliser avec beaucoup de précaution.
Pour "++i" ça doit marcher.
Pour :
i = (DoLock == true ? i+1 : i ) ;
ça doit très probablement ne pas marcher. Le résultat de "i+1" peut être mis dans une "variable temporaire" puis copié dans i.
Mon lock ne marcherait pas s'il fait :
if (i==0) { ++i ; }
Mais ce n'est pas ce qu'il fait.
Il y a effectivement des instructions asm pour faire une incrémentation et un test de façon atomique (il y en a plusieurs).
> D'ailleur c'est pas pour rien que les mutex pthread sont en partie écrit en asm : pour avoir le moins d'overhead possible
Les mutex phtread, ne font pas que ce que je fais (avec la fonction lock()). Il y a spinlock pour un nombre de cycle limité, il y a vérification si c'est un système smp ou non (si c'est mono-cpu, inutile de faire le spinlock et il faut passer directement en sommeil), il enregistre l'id du thread qui fait le lock pour donner un warning si le thread qui fait l'unlock n'est pas le même, les mutex phtread sont inter-processus, mon lock() ne l'ai pas, etc...
> C'est tres simple d'avoir plus d'un million de lock par seconde.
Dans ce cas j'ai envis de dire que c'est compliqué pour ne pas faire ce million de lock par seconde.
Avec volatile (et du matos correcte), il y a plein de cas où on peut éviter les locks. Et ça marche, je le fais courrament sur des trucs qui tourne 24h/24. Par contre, je le fait avec beaucoup de précaution et uniquement pour int, long et pointeur. Il y a même des systèmes (nombreux) qui n'ont pas besoin de "volatile" :-) Les cpus/cache vérifient tout.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
Pas d'accord. C'est généralement le même thread qui fait un GetSemephore (ou équivalent en fonction de l'api) et un ReleaseSemaphore. Forcément.
Le thread prend/demande la ressource, il fait GetSemaphore. Il libère la ressource, il fait ReleaseSemaphore. Il n'y a que le thread qui sait quand il n'a plus besoin de la ressource.
> D'accord pour les mutexs, qui protègent des éléments de possibles accès concurrents
Par forcément.
- Thread 1 prend un lock et lance Thread 2 qui fait le traitement.
- plus tard Thread 1 demande encore le lock mais ne l'obtient que lorsque Thead 2 l'a libéré (une fois qu'il a fini son traitement).
Tu peux avoir la même chose avec un semaphore. Mais un semaphore c'est surtout pour des ressources, pour signaler que tu utilises une ressource. Tu peux utiliser un lock (en général 2) pour synchroniser des threads (et non seulement que protéger des données). Mais en général, c'est à éviter (il est plus clean d'utiliser les signaux ou event). Mais les locks sont extrêmement rapides.
[^] # Re: Alors ca c'est du bon
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 3.
Il faut bien distinguer deux choses :
1) L'auteur du programme _choisit_ d'utiliser du code sous licence proprio.
2) Ce choix implique _l'obligation_ de passer le programme sous licence proprio.
Le choix de l'étape 1) fait que le code sous licence propriétaire impose un changement au programme complet : un passage sous licence proprio. Donc de ce choix résulte une contamination du programme par le code sous licence proprio.
Dans le cas de l'écriture d'un programme, avant de choisir d'intégrer un code, il est nécéssaire de lire sa licence et d'accepter toutes les conséquences. Donc si le code est sous licence proprio, il est nécéssaire d'accepter de modifier la licence de son logiciel. Le code sous licence proprio contamine donc bien le logiciel hôte puisqu'il modifie une de ses caractéristiques.
Donc à mon avis le terme contaminant est tout à fait applicable et représente bien ce qui ce passe lors de l'inclusion de code sous licence proprio dans un autre programme.
CQFD, la GPL n'est en rien plus contaminante que du proprio (si jamais elle est contaminante).
Réfléchissez du point de vu de la GPL et du point de vu d'une autre licence. Et dans ce cas on constate que la GPL n'a rien de contaminant.
[^] # Re: Alors ca c'est du bon
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à -2.
J'ai un code GPL et je veux insérer du proprio.
> Comment diffuser mon code ? Obligatoirement en GPL, puisque sa licence se retrouve imposée du fait de sa cohabitation avec le code importé. J'ai donc été contaminé.
Comment diffuser mon code ? Obligatoirement en proprio, puisque sa licence se retrouve imposée du fait de sa cohabitation avec le code importé. J'ai donc été contaminé.
Si la GPL est contaminance, le proprio aussi.
LA GPL N'EST PAS CONTAMINANTE !!!!
ARRÊTEZ AVEC CE FUD DE MS !!!!
[^] # Re: Et Novell?
Posté par IsNotGood . En réponse au journal Microsoft vous aime.. Évalué à 3.
[^] # Re: Et alors ?
Posté par IsNotGood . En réponse au journal Microsoft vous aime.. Évalué à 3.
M'enfin, la GPL a contaminé toutes les autres licences, donc Mozilla est que sous GPL. Du moins si je comprend bien la substance des propros de MS sur la GPL.
Quoi ?!? MS nous aurait encore mentit ?
[^] # Re: Et alors ?
Posté par IsNotGood . En réponse au journal Microsoft vous aime.. Évalué à 3.
Donc rien ne change ?
Tu devrais dire à MS que Mozilla fait du code sous GPL. Ça fait désordre de voir Mozilla/Firefox/Thunderbird sur la homepage "opensource" de MS.
Et dit à MS de faire attention s'ils bossent avec Mozilla/Firefox/Thunderbird. En effet selon MS, la GPL est virale. Ça serait con que MS-Office ou Vista se retrouve sous GPL à l'insu de son plein grés.
[^] # Re: Et alors ?
Posté par IsNotGood . En réponse au journal Microsoft vous aime.. Évalué à 2.
On a le droit de ne pas y croire, voire d'en rire.
En tout cas, si hier ils étaient sincère (n'est-ce pas pBpG ?), ils ne le sont pas aujourd'hui. Ou l'inverse.
Hier selon MS l'opensource était de la merde, une menace de l'informatique, un truc dangereux et plein de trous de sécurité, sans innovation ni avenir, etc...
Et aujourd'hui ? Ben je préfère ne pas poser la question à MS.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
C'est ridicule, c'est fait en une centaine de cycle cpu maxi. A moins d'avoir plus d'un millions de lock par seconde, ce n'est pas un problème de performance.
> voir une mise en attente si la ressource est indisponible.
Mise en attente qui ne coûte rien puisque le thread n'a rien d'autre à faire.
Si tu ne veux pas de "contexte switch", tu peux remplacer les locks fournit par le système avec un truc dans ce goût :
volatile int i = 0 ;
lock() {
while (true) {
while (i) ;
if (++i == 1) {
break ;
}
else {
// lock déjà pris par un autre
--i ;
}
}
unlock() {
--i ;
}
Ça doit marcher mais tu ne vas pratiquement rien gagner en performance :-(. Si tu as plus de cpu que de thread, tu ne perds pas en performance. Mais si tu as moins de cpu que de thread, tu vas perdre énormément en performance puisque des cpu seront utilisés à faire des "while(i) ;" alors qu'il pourrait faire des trucs vraiment utile.
Donc les locks (mutex, critical section sous windows) ne coûte pratiquement rien et sont très très utiles.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
Ce qui est normal. Et ce n'est pas vraiment aléatoire. Fais des setaffinity sur plusieurs programme et tu va voir que les performances vont dramatiquement chuter. Donc déplacer un thread est tout à fait normal. Et c'est peu coûteux. Si tu veux te convaincre que c'est peut couteux, fais un "make -j nb_cpu+2" et un "make -j nb_cpu". Les deux vont s'éxécuter quasiment aussi vite. Pourtant pour le premier il y aura beaucoup plus de "déplacement" de thread d'un cpu à un autre.
Considère ça :
cpu_1 : thread_A
cpu_2 : thread_B
Thread_A passe en sommeil et thread_C est lancé sur cpu_1 (puisqu'il est disponible)
cpu_1 : thread_C
cpu_2 : thread_B
Thread_B passe en sommeil.
Maintenant le thread_A doit être lancé. Que doit faire l'OS ? Arrêter thread_C, le passer sur cpu_2, le lancer, et lancer thread_A sur cpu_1 ? Ça c'est beaucoup plus coûteux que de lancer thread_A sur cpu_2.
> Il y a quelques générations du noyau de cela, c'était même un ping pong permanent (et très coûteux).
Ce n'est pas coûteux du côté OS. Ça bouffe quasiment autant de cycle. Le problème est qu'il peut y avoir une mauvaise utilisation du cache cpu. Le problème peut être "dramatique" pour certaine architecture. Mais pas sur PC.
S'il est possible qu'un thread s'éxécute sur le même cpu, tant mieux. Mais ne chercher que ça ferait chuter les performances (et gravement).
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 0.
Ce n'est pas très claire. Un processus n'est pas un thread, c'est un environnement (mémoire, variable d'environnement, etc). Un processus a par défaut un thread (celui qui excécute main()). Un processus n'est pas attaché à un cpu pour la bonne raison qu'un processus peut avoir plusieurs threads.
Par exemple :
processus : toto avec 2 thread.
thread 1 de toto : s'exécute sur le premier cpu
thread 2 de toto : s'exécute sur le second cpu
A quel cpu est attaché le processus ? Aucun.
Sous linux aussi a chaque processus il y a au minimum un thread.
Exemple :
[admin@one rsync]$ ls -d /proc/5551
/proc/5551 // processus 5551
[admin@one rsync]$ ls /proc/5551/task/
5551 // thread 5551
C'est un processus (non multi-thread) qui n'a qu'un thread (il doit obligatoirement en avoir au moins un).
La différence avec Windows est que les numéros de processus et de thread son partagé. Sous Linux le numéro du premier thread d'un processus est égale au numéro du processus.
> l'ordonnanceur l'avait décidé (tu comprends, un coeur travaillait à 100%, pas l'autre, alors forcément, l'ordonnanceur a voulu donner du boulot à ce dernier ...).
Tout est normal, l'OS est là pour utiliser au mieux les ressources. Si deux thread sont attachés à un même cpu et qu'un cpu ne fout rien, l'OS va attacher un thread à un autre cpu.
En fait, on ne peut avoir deux threads sur un même cpu. Un thread est réveillé que s'il y a un cpu de disponible. Tout se faire, l'OS peut décider de mettre en sommeil un autre thread (afin de libérer un cpu).
Notons qu'un thread en sommeil n'est pas attaché à un cpu. Donc lorsque l'OS le réveille il peut l'attacher à n'importe quel cpu. Ça ne fait pas plus de boulot pour l'OS. Mais il vaut mieux le rattacher au cpu où il s'exécutait avant car le cache du cpu a peut-être des données que le thread va utiliser.
> mais bien évidemment, c'est plus ou moins indépendant du fait qu'on manipule un mutex ou non.
Pas vraiment. Tant que le thread est actif, il ne change pas de cpu. Mais dès qu'il est en sommeil il peut changer de cpu. Qu'il possède un lock ou soit en attende d'un lock n'y change rien.
Le thread peut passer en sommeil pour différentes raisons :
- l'ordonnanceur estime qu'il a écoulé son quantum de cpu et donc le passe en sommeil pour donner du cpu à un autre thread.
- le thread est passé en sommeil car il attend un lock, un semaphore, la lecture d'un fichier, etc... L'OS peut le changer de cpu au prochain réveil.
Changer de cpu un thread coûte peu. Il peut y avoir des problèmes d'utilisation du cache du cpu.
Exemple : j'ai trois threads mais 2 seulements s'exécute en même temps. Lorsqu'un thread tourne, il le fait pour très très peu de temps.
Imaginons que j'ai thread_A thread_B thread_C et deux cpu : cpu_1 cpu_2.
On peut avoir ce cas :
cpu_1 : thread_A
cpu_2 : thread_B
// thread_A passe en sommeil et thread_C est réveillé
cpu_1 : thread_C
cpu_2 : thread_B
// thread_B passe en sommeil et thread_A est réveillé
cpu_1 : thread_C // le cache de cpu_1a peut-être des données de thread_A
cpu_2 : thread_A
etc...
Les threads n'arrêtent pas de passer de cpu_1 à cpu_2 et vice versa. Le cache des cpu est mal utilisé.
[^] # Re: Alors ca c'est du bon
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 0.
Je tiens à dire que "la GPL est contaminante" est une connerie.
> Maintenant, c'est clairement plus parce qu'ils n'ont pas de main d'oeuvre
Ben Linux aussi utilise du BSD parce (peut-être, entre autre, notamment, etc) qu'ils n'ont pas assez de main d'oeuvre.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 1.
Coder pour tenir compte de la proximité des cpu/core est exceptionnel. Je ne l'ai jamais fait, je ne le ferais sans doute jamais.
Je crois que le noyau Linux affecte les cpu/core au thread en tenant compte de la "proximité" (il ne le fait peut-être que sur certains matos). Mais je ne sais pas du tout ce qui est fait, comment c'est déterminé, etc...
Il y a bien setaffinity() mais ça ne doit être réservé qu'à une appli. Si d'autres applis le font de façon intépendante, c'est une catastrophe en performance. Donc pour moi c'est à éviter.
[^] # Re: Multicoeur ?
Posté par IsNotGood . En réponse à la dépêche Intel libère TBB. Évalué à 0.
"Te soumet potentiellement à un changement de contexte" est vrai.
Mais dans quel cas ?
Il y a changement de contexte s'il n'y a pas assez de cpu (le cpu est alors affecté à un autre thread qui en a besoin). On est dans le cas où il n'y a moins de cpu que de threads actifs/éligibles et au-lieu de laisser un cpu en attende d'un lock, on l'affecte à un autre thread.
Il y a aussi changement de contexte si le thread reste longtemps (c'est très court :-)) en attente du lock. Dans ce cas le thread passe en sommeil et sera réveillé plus tard. On est dans le cas où il n'y a rien à faire pour ce thread/cpu. On ne manque pas de cpu (en nombre, pas forcément en puissance puisqu'on peut attendre le traitement d'un autre cpu). Dans ce cas passer le thread en mode sommeil (et probablement le cpu qui l'exécutait) permet d'économiser de l'énergie. Ceci sans que les performances en souffre ou alors que très faiblement. Le thread qui était en attente (et n'avait rien à faire) sera réveillé un peu moins vite.
Il faut noter qu'on peut faire typiquement des milliers de lock à la second dans une appli multi-threadé. En général il n'y a qu'un faible pourcentage de ces locks qui demande un changement de contexte (si on a un nombre de cpu adapté à l'appli).
Plus techniquement (mais en très simplifié) un mutex fait en premier :
while (!ma_condition && ++compteur < boucle_attente) ;
Si le thread/cpu sort de la boucle et que ma_condition est vrai, il continue, sinon il passe en sommeil et l'OS le réveillera lorsque ma_condition devient vrai.