Ce
#pragma omp parallel for
for (int i = 2; i < N; i++)
for (int j = 2; j < N; j++)
{
arr[i][j] = arr[i-2][j] +arr[i][j-2];
}
va toujours être une source de douleur et de sortie imprévisible. Le temps d'exécution OpenMP va remettre à chaque thread une plage de valeurs pour i
et les laisser. Il n'y aura pas de déterminisme dans l'ordre relatif dans lequel les threads sont mis à jour arr
. Par exemple, alors que le thread 1 met à jour les éléments avec i = 2,3,4,5,...,100
(ou autre) et le thread 2 met à jour les éléments avec i = 102,103,104,...,200
, le programme ne détermine pas si le thread 1 met à jour arr[i,:] = 100
avant ou après que le thread 2 souhaite utiliser les valeurs mises à jour dans arr
. Vous avez écrit un code avec une course de données classique .
Vous avez un certain nombre d'options pour résoudre ce problème:
Vous pourriez vous contorsionner en essayant de faire en sorte que les fils sont mis à jour arr
dans l'ordre (ie séquentiel). Le résultat final serait un programme OpenMP qui s'exécute plus lentement que le programme séquentiel. NE PRENEZ PAS CETTE OPTION.
Vous pouvez faire 2 copies de arr
et toujours mettre à jour de l'un à l'autre, puis de l'autre à l'un. Quelque chose comme (très pseudo-code)
for ...
{
old = 0
new = 1
arr[i][j][new] = arr[i-2][j][old] +arr[i][j-2][old];
old = 1
new = 0
}
Bien sûr, cette seconde approche métiers espace pour le temps, mais qui est souvent un compromis raisonnable.
Vous pouvez constater qu'ajouter un plan supplémentaire à arr
n'accélère pas immédiatement les choses car cela détruit la localité spatiale des valeurs tirées dans le cache. Expérimentez un peu avec ceci, faites peut-être [old]
le premier élément d'index plutôt que le dernier.
Puisque la mise à jour de chaque élément de la matrice dépend des valeurs trouvées dans les éléments 2 lignes/colonnes, vous divisez efficacement la matrice comme un échiquier en éléments blancs et noirs. Vous pouvez utiliser 2 threads, un sur chaque «couleur», sans que les threads ne courent pour accéder aux mêmes données. Encore une fois, cependant, la perturbation de la localité spatiale dans le cache pourrait avoir un impact négatif sur la vitesse.
Si d'autres options se produisent à moi, je vais les modifier dans.
Afficher le code que vous avez essayé. –
Voulez-vous vraiment dire «i
Vicky
Considérant que vous modifiez le conteneur que vous lisez, vous devez faire très attention à la structure de vos opérations parallèles par rapport à une opération en série. J'avais lu un bon livre sur le multithreading en C++, c'est un peu trop large pour une question générale de SO. –