Question

Il suffit d'écrire un petit test de OMP, et il ne fonctionne pas correctement tous les temps:

#include <omp.h>
int main() {
  int i,j=0;
#pragma omp parallel
  for(i=0;i<1000;i++)
  {
#pragma omp barrier
    j+= j^i;
  }
  return j;
}

L'utilisation de j pour l'écriture de toutes les discussions est incorrect dans cet exemple, mais

  • il doit y avoir seulement une valeur non déterministes de j

  • J'ai un gel.

Compilé avec gcc-4.3.1 -fopenmp a.c -o gcc -static

Exécuter sur le serveur Linux x86_Core2 4-core: $ ./gcc et le gel obtenu (parfois, comme 1 gel pour 4-5 courses rapides)

.

Strace:

[pid 13118] futex(0x80d3014, FUTEX_WAKE, 1) = 1
[pid 13119] <... futex resumed> )       = 0
[pid 13118] futex(0x80d3020, FUTEX_WAIT, 251, NULL <unfinished ...>
[pid 13119] futex(0x80d3014, FUTEX_WAKE, 1) = 0
[pid 13119] futex(0x80d3020, FUTEX_WAIT, 251, NULL                       
                        <freeze>

Pourquoi dois-je un gel (blocage)

Était-ce utile?

La solution

Essayez de faire i privée de sorte que chaque boucle a sa propre copie.

Maintenant que j'ai plus de temps, je vais essayer d'expliquer. Par des variables par défaut dans OpenMP sont partagés. Il y a quelques cas où il y a des défauts qui font des variables privées. régions parallèles ne sont pas l'un d'entre eux (si la réponse de haute performance Mark est faux). Dans votre programme d'origine, vous avez deux conditions de course - un sur i et un sur j. Le problème est avec celui sur i. Chaque thread exécutera la boucle un certain nombre de fois, mais étant donné que i est en cours de modification par chaque fil, le nombre de fois un thread exécute la boucle est indéterminée. Étant donné que toutes les discussions doivent exécuter la barrrier pour la barrière à satisfaire, vous venez avec le cas où vous aurez un coup sur la barrière qui ne finira jamais, car tous les threads exécuter le même nombre de fois.

Comme indique clairement la spécification OpenMP (barrière V3.0 spécification OMP, section 2.8.3 Construct) que « la séquence des régions et des régions worksharing barrières rencontrées doivent être même pour chaque fil dans une équipe », votre programme est non conforme et en tant que telle peut avoir un comportement indéterminé.

Autres conseils

Vous essayez d'ajouter au même endroit de plusieurs threads. Vous ne pouvez pas faire ce que vous essayez de faire en parallèle. Si vous voulez faire une somme en parallèle, vous devez diviser en petits morceaux et les recueillir par la suite.

Mise à jour par A5B: bonne idée mais mauvaise partie du code a été repéré. La variable i est modifiée par les deux threads.

  

@ejd, Si je je marque comme privée, sera mon programme est conforme?

Désolé - j'ai vu juste cette question. Techniquement, si vous marquez variable « i » comme votre programme privé sera conforme OpenMP. Cependant, il y a encore une condition de course sur « j » et alors que votre programme est conforme (car il y a des cas valides d'avoir des conditions de course), la valeur de « j » est non spécifiée (selon la spécification OpenMP).

Dans une de vos réponses précédentes, vous avez dit que vous essayez de mesurer la vitesse de la mise en œuvre de la barrière. Il existe plusieurs « points de repère » que vous voudrez peut-être regarder qui ont publié des résultats pour une variété de constructions OpenMP. L'un a été écrit par Mark Bull (EPCC, Université d'Edimbourg), un autre (Sphinx) vient de Lawrence Livermore National Labs (LLNL), et le troisième (Parkbench) provient d'un partenariat informatique japonais. Ils peuvent vous offrir quelques conseils.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top