68 votes

En 2001, le Bureau de l'évaluation a entrepris l'évaluation de deux programmes de pays.

Compte tenu de l'appel de fonction suivant:

f(g(), h())

depuis l'ordre d'évaluation des arguments d'une fonction est indéterminée (encore le cas en C++11 pour autant que je suis au courant), une mise en œuvre théoriquement exécuter g() et h() en parallèle?

Telle une parallélisation ne pouvait coup de pied dans ont été g et h connu pour être assez trivial (dans le cas le plus évident, l'accès uniquement les données locales de leur corps) afin de ne pas introduire des problèmes de concurrence, mais, au-delà de cette restriction, je ne vois rien de l'interdire.

Ainsi, la norme le permet-il? Même si ce n'est par la que-si la règle?

(Dans cette réponse, Mankarse affirme le contraire; cependant, il ne cite pas la norme, et ma lecture par le biais de l' [expr.call] n'a pas révélé de toute évidence une formulation.)

42voto

Mankarse Points 22800

L'exigence vient d' [intro.execution]/15:

... Lors de l'appel d'une fonction ... Chaque évaluation dans la fonction appelante (y compris d'autres appels de fonction) qui n'est pas spécifiquement séquencée avant ou après l'exécution du corps de la fonction appelée est pour une période indéterminée séquencé à l'égard de l'exécution de la fonction appelée [Note de bas de page: En d'autres termes, la fonction d'exécutions ne pas entrelacer les uns avec les autres.].

De sorte que toute l'exécution du corps de l' g() doit être pour une période indéterminée séquencé (qui est, non pas de chevauchement avec) l'évaluation de l' h() (parce qu' h() est une expression de la fonction appelante).

Le point essentiel ici est que l' g() et h() sont à la fois des appels de fonction.

(Bien sûr, le comme-si la règle signifie que la possibilité ne peut pas être entièrement exclue, mais elle ne doit jamais se faire d'une manière qui pourrait affecter le comportement observable d'un programme. Tout au plus, une telle mise en œuvre voudrais juste modifier les caractéristiques de performance du code.)

16voto

Dietmar Kühl Points 70604
<p>Tant que vous ne pouvez pas dire, quel que soit le compilateur effectue pour évaluer ces fonctions appartient entièrement au compilateur. Clairement, l’évaluation des fonctions ne peuvent être liées à l’accès aux données partagées et mutables car cela introduirait des concurrences de données. Le principe de base est le « comme si »-règle et les opérations fondamentales observables, c'est-à-dire les accès aux <code></code> données, opérations d’e/s, accès aux données atomiques, etc.. L’article pertinent est 1,9 [intro.execution].</p>

3voto

Nicol Bolas Points 133791

Non, sauf si le compilateur savait exactement ce qu' g(), h(), et rien de ce qu'ils appellent.

Les deux expressions sont des appels de fonction, ce qui peut avoir des effets secondaires inconnus. Par conséquent, la parallélisation pourrait entraîner de données de course sur les effets secondaires. Depuis la norme C++ ne permet pas l'argument de l'évaluation à cause de données de course sur les effets secondaires des expressions, le compilateur ne peut paralléliser si il sait qu'aucun de ces données course est possible.

Que signifie marcher si chaque fonction et de regarder exactement ce qu'ils font et/ou de l'appel, puis suivi par le biais de ces fonctions, etc. Dans le cas général, il n'est pas possible.

1voto

nevsan Points 657

La réponse est facile: quand les fonctions sont séquencés, même si pour une période indéterminée, il n'y a pas de possibilité pour une condition de concurrence entre les deux, ce qui n'est pas vrai si elles sont mises en parallèle. Même une paire de une ligne "trivial" fonctions pourrait le faire.

void g()
{
    *p = *p + 1;
}


void h()
{
    *p = *p - 1;
}

Si p est un nom partagé par g et h, puis d'un séquentiel d'appel d' g et h dans n'importe quel ordre sera le résultat d'une valeur pointée par p de ne pas changer. Si elles sont mises en parallèle, la lecture de *p et l'attribution de il pourrait être entrelacées de manière arbitraire entre les deux:

  1. g lectures *p et trouve la valeur 1.
  2. f lectures *p et trouve aussi la valeur 1.
  3. g écrit 2 *p.
  4. f, toujours en utilisant la valeur 1 qu'il se lisait avant écrira 0 *p.

Ainsi, le comportement est différent lorsqu'elles sont mises en parallèle.

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