81 votes

Que signifie l'attribut [[carry_dependency]]?

Quelqu'un peut-il l'expliquer dans une langue que les simples mortels comprennent?

63voto

Anthony Williams Points 28904

[[carries_dependency]] est utilisé pour permettre à des dépendances à l'ensemble des appels de fonction. Cela permet au compilateur de générer un code de meilleure qualité lorsqu'il est utilisé avec std::memory_order_consume pour le transfert de valeurs entre les threads sur les plates-formes avec des mal-ordonnées d'architectures tels que IBM POWER architecture.

En particulier, si une valeur de lire avec memory_order_consume est passé à une fonction, puis, sans [[carries_dependency]], alors le compilateur peut émettre un mémoire en clôture de l'instruction afin de garantir que la mémoire de la commande de la sémantique sont respectés. Si le paramètre est annotée avec l' [[carries_dependency]] alors que le compilateur peut supposer que le corps de la fonction va exécuter correctement la dépendance, et cette clôture peut ne plus être nécessaire.

De même, si une fonction retourne une valeur chargé avec des memory_order_consume, ou déduite d'une telle valeur, alors, sans [[carries_dependency]] le compilateur peut être nécessaire d'insérer une clôture d'instruction afin de garantir que les mesures de la mémoire de commande de la sémantique sont respectés. Avec l' [[carries_dependency]] d'annotation, cette clôture peut ne plus être nécessaire, que l'appelant est maintenant responsable du maintien de l'arbre des dépendances.

par exemple

void print(int * val)
{
    std::cout<<*p<<std::endl;
}

void print2(int * [[carries_dependency]] val)
{
    std::cout<<*p<<std::endl;
}

std::atomic<int*> p;
int* local=p.load(std::memory_order_consume);
if(local)
    std::cout<<*local<<std::endl; // 1

if(local)
    print(local); // 2

if(local)
    print2(local); // 3

En ligne (1), la dépendance est explicite, de sorte que le compilateur sait qu' local est déréférencé, et qu'il doit veiller à ce que la chaîne de dépendances est conservé afin d'éviter une clôture sur le POUVOIR. En ligne (2), la définition de l' print est opaque (en supposant qu'il n'est pas inline), de sorte que le compilateur doit émettre une clôture afin de s'assurer que la lecture de *p en print renvoie la valeur correcte. Sur la ligne (3), le compilateur peut supposer que, bien que print2 est aussi opaque alors que la dépendance du paramètre à la valeur déréférencée est conservé dans le volet enseignement, et pas de clôture est nécessaire sur le POUVOIR. Évidemment, la définition de l' print2 doit effectivement conserver cette dépendance, de sorte que l'attribut aura également un impact sur le code généré pour l' print2.

-2voto

user3221894 Points 11

En bref, je pense que, s'il y a carries_dependency attribut, le code généré pour une fonction doit être optimisé pour un cas, lorsque l'argument réel va vraiment venir de l'autre thread et porte une dépendance. De même, pour une valeur de retour. Il y a peut être un manque de performance, si cette hypothèse n'est pas vrai (par exemple un thread unique programme). Mais aussi l'absence de [[carries_dependency]] peut entraîner de mauvaises performances dans le cas contraire... Pas d'autres effets, mais la performance alter devrait se produire.

Par exemple, le déréférencement de pointeur fonctionnement dépend de la façon dont le pointeur a été obtenu précédemment, et si la valeur du pointeur p est fourni à partir d'un autre thread (en "consommer" de l'opération) la valeur attribuée précédemment par un autre thread *p sont prises en compte et visible. Il y a peut être un autre pointeur q qui est égale à p (q)==p), mais que sa valeur ne provient pas que d'autres thread, la valeur de *q peut être vu de différentes de la *p. Effectivement *q peut provoquer une sorte de "comportement indéfini" (en raison de l'accès de la mémoire de l'emplacement de la coordination avec l'autre thread qui fait de la cession).

Vraiment, il semble qu'il y a certains gros bug dans la fonctionnalité de la mémoire (et l'esprit) dans certains ingénierie des cas.... >:-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X