9
votes

Deux hommes std :: atomiques de faire partie d'un syndicat?

Je veux le faire.

union {
    uint128_t u128;
    struct {
        uint64_t u64_1;
        uint64_t u64_2;
    };
};


4 commentaires

Votre plate-forme de soutien 128bit écrit atomiques en mode natif?


En raison de restrictions aliasing (au moins) vous ne pouvez pas écrire U128 et lire u64_1 et u64_2, ou vice versa. Aussi C ++, C ++ même 11, ne pas structs anonymes.


On dirait un BFG-3000 avec un détecteur intégré pied pour moi ...


@dribeas, oui, instruction CMPXCHG16.


4 Réponses :


0
votes

Il devrait être bien aussi longtemps que

1 vous respecte aliasing strict;

2 vous ne met pas à jour U128 et soit de u64_1 ou u64_2 en même temps (ce qui est bien sûr pas protégé ici et n'a pas de sens de toute façon);

3 vous ne vous attendez pas u64_1 et u64_1 pour cartographier la première et deuxième 64 bits de U128 .

Je ne vois pas en fait aucun avantage de cette construction. Peut-être que vous pouvez expliquer pourquoi cette construction devrait être utile. Je pense que vous pouvez être mieux sans U128 (à savoir sans union).


1 commentaires

Je pense qu'il veut des fils pour tenter simultanément des modifications sur les 128bits ou le haut / bas 64bit (qui est, les opérations entremêlés): écriture 128, lecture 64, écriture 64, lu 128 ... qui ne sont pas tout à fait garantissaient



0
votes

En supposant que vous voulez être en mesure d'utiliser simultanément tous les membres du syndicat:

portably, non. Cela ne va pas avoir un comportement défini. Considérer que l'un ou les deux types peuvent être mis en œuvre avec mutex pour fournir le verrouillage

limité à un application spécifique sur laquelle tous les types atomiques impliqués ont lockfree implémentations, il est très probable de travailler correctement, ou moins correctement serait comme le cas d'une union similaire de non-Atomics.


3 commentaires

Eh bien, C ++ 11 permet d'avoir des syndicats non-POD, aussi longtemps que vous suivez toutes les règles et ne pas oublier d'invoquer le cteur / dtor manuellement ... Trop Checklist bien.


@MaximYegorushkin Désolé, j'oublie de préciser l'hypothèse que l'OP veut modifier tous les membres en même temps, ce qui était ma lecture de « Plusieurs threads lire et écrire les deux parties de l'union. »


qui entraînerait un comportement non défini



7
votes

std :: atomique opérations peut être lockless ou verrouillage, selon que les offres d'architecture des garanties sous-jacentes. Vous pouvez vérifier cela en vérifiant std :: atomique :: is_lock_free () .

Si le type n'est pas verrouiller libre, il peut être pris en charge par la bibliothèque au moyen d'un compteur. Cela, à son tour probablement signifie que le type est plus un sous POD, qui signifie à son tour qu'il est de votre responsabilité d'appeler les constructeurs / destructeurs lors du passage d'un membre actif du syndicat à l'autre.

S'il y a un mutex pour la 128 bits, mais pas les types 64bit vous pourriez vous retrouver avec une situation dans laquelle la disposition des valeurs coïncide, mais l'atomicité des opérations est assurée par différents moyens, donc il peut sembler au travail , mais ne parviennent pas et spuriously d'une manière qui est difficile à détecter même.


6 commentaires

§ 29.5 / 5 dit « Les spécialisations intégrales atomiques et la spécialisation atomique ont mise en page standard. Ils ont chacun un constructeur par défaut trivial et un destructor trivial. Ils doivent la syntaxe d'initialisation globale chaque support. " Donc, pas d'appels constructeur / destructor sont nécessaires pour changer le membre actif du syndicat.


@Casey: Oui, je lisais avant d'écrire la réponse. La question est de savoir si uint128_t est un type intégral conformément à la norme. Le point important est que si le type est nativement pris en charge, il faudra utiliser un mécanisme de synchronisation sous-jacente, et il n'y a aucune garantie que le mécanisme de synchronisation est mise en page standard ou non.


@Casey: Notez également que standard layout et POD ne sont pas équivalents. Tous les cabosses mise en page standard, mais pas tous les types de mise en page standard sont POD. Lisez le deuxième paragraphe: si le std :: atomique ne dispose pas d'un constructeur trivial ...


Il est donc sûr que tant qu'il est sans verrou?


@alkedr: presque garanti d'être dangereux voire bloquer sans, mais si elle est moi sans verrou serait toujours regarder dans ce que les offres de matériel et ce que votre mise en œuvre bibliothèque. uint128_t n'est pas un type standard, et il n'y a pas que de nombreuses plates-formes avec 128bit registres, donc je serais surpris si cela peut être garantie. Cela dépend aussi de ce que les opérations que vous faites, si elle est seulement en lecture / écriture ou si vous utilisez une autre fonction (par incréments de façon atomique ou décréments ...). Je ne me risquerais pas à dire qu'il est sûr, même si elle est sans verrou


@dribeas, CMPXCHG16 instruction est supportée par la majorité des processeurs 64 bits. 128bit registres ne sont pas nécessaires, deux registres 64 bits sont utilisés à la place.



4
votes

D'une manière générale ce n'est pas sûr. La note (Admitedly non normatif) à 29,5 / 9 nous dit que:

[Note: La représentation d'un besoin de spécialisation atomique pas la même taille que le type d'argument correspondante. spécialisations devraient avoir la même taille chaque fois que possible, car cela réduit la effort requis pour le code existant du port. -end ndlr]

Alors dès le départ nous ne sommes pas garanti que les deux pièces ont même la même taille. De plus, vous devez vous assurer que vous n'utilisez pas une opération atomique sur un membre, tandis qu'un autre fil change le membre actif dans un autre.


3 commentaires

Les deux membres sont actifs tout le temps


@alkedr Le standard C ++ dit explicitement que seul un membre d'un syndicat est actif à la fois.


@alkedr: Mark est correct. Il est un mythe que les syndicats peuvent avoir plusieurs membres actifs à un moment donné. Beaucoup de gens utilisent les syndicats pour cette seule raison et ils ont tort. [C ++ 11 9,5 / 1]: Dans une union, au plus l'un des éléments de données non-statique peut être actif à tout moment, qui est, la valeur d'au plus l'un des éléments de données non-statique peuvent être stockés dans une union à tout moment. [..]