Hello,
on n'a pas mal argument� le pour et contre le COW dans Qt,
http://blogs.qtdeveloper.net/archive...it-2/#more-158
Qu'en pensez-vous ?
Version imprimable
Hello,
on n'a pas mal argument� le pour et contre le COW dans Qt,
http://blogs.qtdeveloper.net/archive...it-2/#more-158
Qu'en pensez-vous ?
http://blog.developpez.com/index.php...&c=1&tb=1&pb=1
Je suis content qu'il ait d�montr� que la m�thode de Trolltech soit plus rapide. Apr�s les tests de Sutter, j'avais un doute, mais les optimisations de Qt ont fait le travail + les QString ne sont pas les plus critiques pour ce genre de choses - imaginez les benchmarks sur des QList ! -
Je me pose la question d'inclure un pointeur Qt plut�t qu'un pointeur Boost dans ma biblioth�que matricielle...
tu revises donc ta position ? :)
qu'entends-tu par les benchmarks sur les lists ?
Les QList sont aussi partag�es implicitement.
En fait, je n'avais jamais eu de position fixe ;)
oui c'est clair, les Qlist ca evite beaucoup de recopie et permet un design plus propre en retournant la liste.
mais tu n'etais pas pour la stl a tout pris ? ;)
enfin tout le monde peut changer d'avis hein ? :D
Comme l'a dit je ne sais plus qui : Il ne faut jamais croire un benchmark que l'on n'a pas truqu� soit-m�me ;)
En l'occurence, je n'ai pas eu l'occasion de le tester sur ma machine, de jouer avec... Je ne dis pas que je j'y crois, ni que je n'y crois pas.
Par contre, en jettant un oeil rapide sur le code, je ne vois pas en quoi les cha�nes sont partag�es entre les diff�rent thread ?
Le comportement de std::string d�pend de l'impl�mentation, cellede libstdc++ utilise d�j� du copy-on-write et pas vraiment de mani�re optimis�e pour le multithread� d'apr�s ce que je sais.
Et en regardant les r�sultats des benchmarks je ne vois rien qui explicite que les solutions de Qt sont mieux.
J'ai survol� les benchs.
Comme je disais par mail � Aur�lien. La pertinence du COW m'�chappe toujours.
Je veux bien volontier admettre un int�r�t � des cha�nes non mutables partag�es. Mais pas � des COW partag�es dans divers threads.
Mes sc�narios de manipulation de chaines consistent g�n�ralement � construire ces chaines et � ensuite les figer. Apr�s �ventuellement elles sont dans des t�ches (ace) partag�es entre plusieurs threads, ou exp�di�es d'une t�che � l'autre. Et si j'avais des modifs � faire, cela correspondrait � des reset, mais pas � des utilisations de [] ou de quoique ce soit qui active une copie sur �criture.
Du coup les benchs qui me semblent les plus pertinents (je ne les ai plus en t�te) sont ceux:
- de construction (et encore)
- ceux d'acc�s "globaux" pour quand on veut s�rialiser vers une autre structure ; on utilise alors directement le pointeur sous-jascent ; ne devrait pas couter grand chose, m�me avec du COW
- ceux d'acc�s "atomique" pour ceux qui ecrivent des boucles avec [] sur tous les �l�ments des chaines ; l� le COW ne devrait pas �tre si bon je pense.
Le co�t de la copie de type chaine � type cha�ne ? Est-ce si pertinent ?
Mes param�tres sont pris par r�f�rence constante (ce qui n'est pas le cas d'un de leurs benchs :?). Je ne fais pas de copies pour le plaisir de faire des copies -- � la limite pour un nouvel object qui recopie la chaine re�ue lors de sa construction, ici OK pour des non-mutables partag�es et r�initialisables.
Mes retours vont utiliser RVO et RNVO (quand possible), un jour les lvalue reference (je l'esp�re). L� effectivement, on n'a pas de s�mantique de d�placement native... OK pour cet avantage l�. Bien que la non-mutable partag�e est tr�s bien aussi, voire carr�ment que le comptage non prot�g� contre le multithread. (*)
(*) Dans le genre il aurait fallu un constructeur � std::list qui prenne un std::auto_ptr<std::list> et qu'il s'impl�mente par un swap. Bon, c'est sale et cela fait plus de types, et cela emp�che les R*VO, c'est vrai.
Pour les concat�nations, il existent d'autres techniques qui torchent (cf les concatenators pr�sent�s par Matthew Wilson dans Imperfect C++ et donc pr�sents dans stl_soft -- bien que je serais plus parti sur une approche de meta-prog plut�t que l'approche dynamique qu'il a choisie)
Pour revenir � QT, vu qu'ils utilisent un proxy, cela m�rite de ressortir le MEC++ pour voir si il n'y aurait pas des effets de bord bizarres.
Je suis aussi tr�s surpris des r�sultats de GCC. Je savais pour le COW, mais je vois rien qui justifie les �carts. A part une tr�s mauvaise impl�mentation du comptage atomique, ou d'autre chose.
A propos de RVO/RNVO je me demande qu'elle sont les options de compils retenues dans les bench vu les co�ts de certains appels. Bref, il faudra que je remesure tout cela chez moi.
Je ne vois pas pourquoi les pointeurs intelligents de QT seraient plus efficaces que ceux de boost qui reposent aussi sur des compteurs atomiques (ou non dans le cas de boost compil� en mono-thread). Sans parler de la richesse de l'interface qui fait que les boost::shared_ptr sont en fait des shared_ressource.
PS: d�s que j'ai un moment je m'occupe s�rieusement de ces transcripts :-(
Pou Qt, il faut aussi voir �a de mani�re plus g�n�rale que juste pour les string. Ils partagent ainsi les donn�es de toutes leurs classes qui ont un minimum de donn�es - P_IMPL idiome pour assurer une compatibilit� binaire entre les versions de Qt -.
Pour des ca�nes partag�es entre les threads, dans Qt3, ce n'�tait pas le cas, et apparemment ils ont eu un retour n�gatif sur ce probl�me car on devait forcer la copie compl�te. Maintenant, on peut s'en passer, c'est plus transparent. De plus, leur comptage atomique est efficace, du moins plus efficace qu'une recopie, et leurs mutex qui utilisent aussi leur classe atomique est plus rapide qu'un mutex traditionnel.
Voir aussi:
http://blogs.qtdeveloper.net/archive...the-benchmark/
Pour info, l'auteur de ce benchmark a �t� interview� par developpez.com quelques jours avant de publier ses r�sultats. On va bient�t publier tout �a... (ben oui je fais du teasing :D)
rvalue references plut�t non ?Citation:
un jour les lvalue reference (je l'esp�re)
De mani�re dynamique, une structure comme sgi rope devrait aussi fournir de bons r�sultats pour la concat�nation.Citation:
Pour les concat�nations, il existent d'autres techniques qui torchent
Il y a un truc que je trouve louche l�.Citation:
Envoy� par Miles
Si on pouvait impl�menter des mutex avec des compteurs atomiques, pourquoi est-ce que les autres impl�mentations de mutex ne proc�deraient pas aussi de la sorte pour avoir un truc plus efficace ?
(ceci n'est pas une question comme dans "je connais la r�ponse, mais pose toi aussi la question". Mais comme dans "je n'en sais strictement rien". Je ne me suis jamais pos�e cette question)
arf. Oui au temps pour moi. Je me plante toujours.Citation:
Envoy� par loufoque
Note: je suis quelqu'un de tr�s atypique en ce qui concerne la programmation multithread. Je joue encore avec, mais mon exp�rience est essentiellement dans le cadre de programmation en Ada, il y a une dizaine d'ann�e. Je peux �tre compl�tement � c�t� de la plaque.Citation:
Envoy� par Luc Hermitte
Un mutex doit n�cessairement recourir � l'OS s'il ne peut pas se contenter d'�tre du polling sur une variable, consommant du CPU pour rien. Une possibilit� est que les mutex de QT fasse un peu de polling avec des algo lock-free (�ventuellement un seul passage peut �tre un gain) puis prennent un lock via l'OS. On a un gain si la lib n'utilise pas d�j� ce truc (ce qui m'�tonnerait un peu, je le connais et je suis plut�t rouill� en la mati�re) et que le lock est g�n�ralement soit libre soit pris par un process tournant sur un autre processeur qui le lib�re rapidement.
vous etes vraiment sure que les mutexes dans Qt sont implement�s avec des compteurs atomiques ?
moi je ne pense pas du tout.
C'est �a, je crois. En tout cas, s'ils l'utilisent, c'est apr�s avoir v�rifi� dans la doc et dans les benchs qu'un mutex traditionnel comporte beaucoup d'aller-et-venues, et avoir une op�ration atomique pour tenter d'avoir un lock est plus rapide tout de m�me.Citation:
Envoy� par Jean-Marc.Bourguet
Je pense serieusement que les compteurs atomiques sont seulement utilis�s pour le implicit sharing.
... atomic counting n'est pas de la mise en attente du thread sur une resource prot�g�
Dans les op�rateurs atomiques, il n'y a pas que l'incr�mentation, il y a aussi le set and test, et �a, �a sert pour les mutex. Et c'est certain qu'ils s'en servent cf un article dans qqs jours sur "Qt in depth".
Parce qu'on veut dans certains cas en avoir plus ? Par exemple, sous windows, un mutex est partageable entre processus. Il y existe aussi un objet (mal) nomm� CriticalSection, qui est en fait un mutex non partageable entre processus, et qui a de bien meilleures perfs.Citation:
Envoy� par Luc Hermitte
a priori qt se sert du comptage atomique pour faire des mutexes recursifs.
mais le wait et le wakeup utilise bien un mutex pthread (sous macos)
a+
Oui, il utilise un mutex standard apr�s. Mais au d�part, pour acc�lerer, il utilise un test and set atomique - j'ai l'info directement du concepteur du syst�me... -
tu en as de la chance toi !!!
moi je l'ai vu dans le code :)
La vid�o de la pr�sentation devrait �tre dispo le mois prochain :D
Si longtemps :aie: ?
Apr�s la conf�rence de San Jose... (c'est la video de Trolltech).
Il faudra que je reregarde comment ils proc�dent dans ACE -- ils ont quantit�s de mutex, locks et gardes diff�rents. Sans parler des diverses polices pour param�trer tout cela.
Sinon, dans ce dernier "th�me" je suis tomb� sur �a aujourd'hui. http://www.artima.com/cppsource/threads_meeting.html (compte rendu de la derni�re r�union du commit� de standardisation au sujet du support du multi-threading dans le C++0x)
Tr�s int�ressant.
En ce qui concerne les critical sections sous Windows:
http://support.microsoft.com/kb/105678/en-us
Il y a aussi les fonctions InterlockedXXX
http://msdn.microsoft.com/library/en...ronization.asp
Ce n'est pas la derni�re... La derni�re est en cours actuellement.. ;)Citation:
Envoy� par Luc Hermitte
A part �a, j'ai d�couvert ce doc, qui a l'air assez sympa aussi http://www.cs.utah.edu/~wilson/compi...04-michael.pdf. Faudra que je le lise au calme.
donc en fait Qt a fait le bon choix ... ?
je dis cela parce que j'observe un revirement assez impressionnant sur le COW ...
mais ca me rassure croyez moi :lol:
C'est pas qu'ils on fait le bon choix, c'est simplement qu'ils ont ajout� un refcounting plus optimis� pour le multi-thread�.
Pas de quoi casser trois pattes � un canard...
Sans cette optimisation, en faisant des copies � chaque fois dans leurs programmes, le CPU grimperait de 50% d'apr�s des tests qu'ils ont fait.
Je crois que c'est le gain m�moire qui est de 50% dans le designer, + un gain visible en terme de vitesse d'ex�cution (difficile � quantifier).
Ah ? JE croyais que c'�tait le temps CPU... De toute mani�re, on verra vite :DCitation:
Envoy� par Aurelien.Regat-Barrel
Yep :D Il me semble que c'est les 2 (tant qu'� faire).
Quel revirement de situation quand meme ! ;)
En m�me temps, il y a s�rement moyen d'�viter cette d�gradation en utilisant moisn de copies, ...
C'est un cercle vicieux ! Ils ont le COW. Des d�veloppeurs d�cident alors de passer par copie au lieu de passer par r�f�rence. Donc, dans ces programmes, les perfs baissent notablement si on n'utilise plus le COW. Donc on pr�tend que le COW fait gagner du temps.Citation:
Envoy� par Miles
Si on me dit qu'un programme typique fait par une personne un minimum comp�tente sans COW, puis port� dans un environnement COW se comporte XX% plus vite pourquoi pas. Mais l�, j'ai quelques doutes.
J'ai pas fait trop de tests, mais je n'ai clairement pas l'impression que mes programment passent une partie mesurable de leur temps dans des copies de cha�nes inutiles.
pas seulement de chaines mais de collection, set, map etc...
et sans compter un design clair et une relecture facile.
C'est surtout par rapport � la valeur de retours dans les fonctions je crois. Avec la STL, tu es oblig�s "d'optimiser � la main" en jouant avec swap:
Avec l'approche de Qt l'�criture est all�g�e. Y'a du pour et y'a du contre...Code:
1
2
3
4
5 std::vector<int> get_vect(); std::vector<int> v; v.swap( get_vect() );
Tout � fait d'accord avec toi, un test sur un programme plus neutre serait plus appropri�, sans nul doute.Citation:
Envoy� par JolyLoic