OVH Cloud OVH Cloud

COW et STL

18 réponses
Avatar
Fabien LE LEZ
Bonjour,

Si j'ai bien compris, il est fréquent que std::basic_string<>
implémente le COW. Mais en est-il de même pour les conteneurs de la
STL ?

Merci d'avance.


--
;-)

10 réponses

1 2
Avatar
kanze
Fabien LE LEZ wrote:

Si j'ai bien compris, il est fréquent que std::basic_string<>
implémente le COW.


Pas si fréquent que ça, je crois. Parmi les dernières versions
des compilateurs, je crois qu'il n'y a que g++ qui l'utilise, et
je crois que g++ a une nouvelle implémentation prévue.

Mais en est-il de même pour les conteneurs de la STL ?


Est-ce que tu le crois permis, étant donné les guaranties sur
les itérateurs ? Modifier une valeur dans un conteneur, par
exemple, ne doit pas invalider un itérateur. Note bien que les
garanties vis-à-vis des itérateurs de std::basic_string sont
beaucoup moins -- la première fonction non-const peut les
invalider.

(En fait, je pourrais le faire assez facilement pour std::vector
ou std::deque, mais au coût de rallentir l'opérateur * sur
l'itérateur, ainsi que la copie et l'affectation de
l'itérateur. Pour std::list, je ne suis même pas sûr que c'est
possible.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Aurélien REGAT-BARREL
Si j'ai bien compris, il est fréquent que std::basic_string<>
implémente le COW.


Ca me fait ressurgir une question. VC++ 7 ne l'implémente plus, alors que
VC++ 6 le faisait. J'ai lu que c'était dû au fait que la norme ne le
permettait pas. Est-ce vrai et pour quelle raison ?

--
Aurélien REGAT-BARREL

Avatar
Fabien LE LEZ
On 23 Feb 2005 00:27:32 -0800, :

Si j'ai bien compris, il est fréquent que std::basic_string<>
implémente le COW.


Pas si fréquent que ça, je crois.


Ça n'a jamais été fréquent, ou c'est une idée de plus en plus
abandonné ?
Est-ce à cause de la pessimisation que ça introduit en multithread ?


--
;-)


Avatar
kanze
Fabien LE LEZ wrote:
On 23 Feb 2005 00:27:32 -0800, :

Si j'ai bien compris, il est fréquent que
std::basic_string<> implémente le COW.


Pas si fréquent que ça, je crois.


Ça n'a jamais été fréquent, ou c'est une idée de plus en plus
abandonné ?


Je crois qu'à une époque, ça a été plutôt la règle.

Est-ce à cause de la pessimisation que ça introduit en
multithread ?


Plus ou moins. Il y a plusieurs choses, en fait :

-- Vue l'interface de std::basic_string, on en gagne moins que
l'on est en droit d'attendre. L'interface laisse des
références vers l'implémentation s'échapper, et dès qu'une
référence non const s'est échappée, l'objet ne sait plus
s'il va être modifié ou non. Du coup, il faut prévoyer, et
bloquer le partage.

-- L'interface aussi est telle qu'il est quasiment impossible
de rendre l'objet thread-safe sans un vrai lock (mutex,
semaphore ou d'autre). Les algorithmes libres de lock ne
marchent pas. Et des vrais locks sont chers.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
kanze
Aurélien REGAT-BARREL wrote:
Si j'ai bien compris, il est fréquent que
std::basic_string<> implémente le COW.


Ca me fait ressurgir une question. VC++ 7 ne l'implémente
plus, alors que VC++ 6 le faisait. J'ai lu que c'était dû au
fait que la norme ne le permettait pas. Est-ce vrai et pour
quelle raison ?


Il y a eu des discussions là-dessus. L'intention des auteurs de
la norme étaient bien de le permettre -- j'ai eu beaucoup de
discussions avec eux lors des commentaires sur le CD2.
Seulement...

Certains prétendent que le suivant serait légal :

std::string s1( "abcdef" ) ;
std::string const& s2( s1 ) ;
const_cast< char >( s2[ 3 ] ) = 'x' ;

L'argument, c'est que l'objet initial (le char, ici) n'est pas
const ; enlever le const au moyen d'un cast et le modifier est
donc légal. Seulement, si tu permets ça, quand est-ce que tu
pourrais partager l'implémentation ? Même une fonction const,
comme l'operator [] ici, devrait être traiter comme une
écriture, et déclencher la copie. Seulement, la fonction const
n'a pas le droit d'invalider d'itérateur ni des références.

Personnellement, je suis sceptique en ce qui concerne cet
argument. Je suis assez sûr que ce n'était pas l'intention. Mais
je suis moins sûr en ce que dit la norme exactement.

Mais le vrai argument réside ailleurs. L'argument contre COW
pour les chaînes, c'est que d'une part, on n'en gagne pas autant
qu'on pourrait le croire -- dès qu'une référence échappe,
l'objet doit considérer qu'il pourrait être modifier, effectuer
la copie, et interdire d'autres copies de lui-même. Or,
l'opérateur [] laisse obligatoirement échapper une référence ;
la norme ne permet pas de proxy.

En plus, l'interface de std::basic_string ne permet pas les
algorithmes sans lock. C-à-d que dans un environement
multi-thread, la seule solution consiste à prendre un lock
(mutex, semaphore, etc.) dans prèsque chaque fonction non const,
qui est cher. Des deux implémentations COW dont je me suis
servi, un (Rogue Wave) prenait le lock, et était
insupportablement lent, l'autre (g++) n'est pas vraiment
thread-safe, au moins selon les normes Posix.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Aurélien REGAT-BARREL
Ok merci pour ces explications.
Pour info la nouvelle std::string de VC++ utilise un buffer interne de 16
octets pour stocker les petites chaines (sur la pile donc) et fait un new si
c'est pas suffisant. Ca doit être leur réponse à la suppression du COW.
--
Aurélien REGAT-BARREL
Avatar
Fabien LE LEZ
On Wed, 23 Feb 2005 15:29:07 +0100, "Aurélien REGAT-BARREL"
:

std::string de VC++ utilise un buffer interne de 16
octets pour stocker les petites chaines (sur la pile donc) et fait un new si
c'est pas suffisant

Ca doit être leur réponse à la suppression du COW.


Je croyais que c'était déjà le cas avant ?


--
;-)

Avatar
dezz
Bonjour,

excusez mon ignorance mais qu'est-ce que le COW ?

Après des recherches rapides, j'ai trouvé que cela signifiait "Copy On
Write" mais je n'ai pas trouvé d'explications claires sur le sujet...

Merci,
Z
Avatar
Jean-Marc Bourguet
dezz writes:

Bonjour,

excusez mon ignorance mais qu'est-ce que le COW ?


Ne pas copier directement une structure mais garder un pointeur vers
l'original et ne faire la copie que quand on modifie (l'original ou la
copie). L'idee est que souvent on ne modifie rien...

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
dezz
dezz writes:


Bonjour,

excusez mon ignorance mais qu'est-ce que le COW ?



Ne pas copier directement une structure mais garder un pointeur vers
l'original et ne faire la copie que quand on modifie (l'original ou la
copie). L'idee est que souvent on ne modifie rien...

A+



N'y a-t-il pas un risque à utiliser cette technique (passage par
référence d'un objet temporaire, ...) ?
Si on ne modifie pas l'objet, pourquoi le garder ?

Dans quels cas, peut-on l'utiliser ?

Merci,
Z


1 2