2017-09-26 2 views
0

J'ai une application qui rend à une texture dans un thread et un autre thread lit les données de cette texture. Le contexte entre les deux threads est partagé. Est-il possible qu'une condition de course se produise où le thread de lecture va lire des données partielles?Est-il possible de rendre une texture pendant son écriture?

+3

Oui, c'est fondamentalement une configuration parfaite pour une course de données. –

+0

@DietrichEpp J'ai lu en ligne que des problèmes peuvent se produire quand quelque chose écrit dans un contexte à partir de deux threads différents, mais je ne trouve rien qui dise les effets de l'écriture sur une seule lecture de l'autre. – Kyle

Répondre

1

De the OpenGL 4.6 core spec, section 5.3.1:

Le contenu d'un T objet sont considérés comme ayant été changés une fois par commande tel que décrit à la section 5.3 est terminée. La fin d'une commande 1 peut être déterminée soit en appelant Finish, soit en appelant FenceSync et en exécutant une commande WaitSync sur l'objet de synchronisation associé.

En général, une course de données se produit lorsque:

  1. Deux ou plusieurs threads écrivent au même endroit dans la mémoire, et

  2. Au moins l'un des fils est écriture et

  3. Il n'y a pas de synchronisation entre les threads.

Vous pouvez voir que dans OpenGL, vous devez soit attendre Finish() ou WaitSync() pour revenir à savoir que vos opérations sont synchronisées. Il existe des règles supplémentaires, la section de la note 5.3.3:

Règle 4 Si le contenu d'un T objet sont modifiés dans un contexte autre que le contexte actuel, T doit être fixé ou refixé au moins un point de liaison dans le contexte actuel, ou au moins un point de rattachement d'un objet conteneur C actuellement lié, afin de garantir que les nouveaux contenus de T sont visibles dans le contexte actuel.

Donc, si vous écrivez à une texture en fil A et le lisez dans le thread B, vous devez effectuer les opérations suivantes:

  1. Créer un objet de synchronisation.

  2. Signale l'objet de synchronisation du thread A une fois l'écriture terminée.

  3. attente pour l'objet de synchronisation en fil B.

  4. REBIND la texture du fil B.

Une fois ces étapes terminées, vous pouvez lire à partir de la texture en fil B.

Note: Vous pouvez constater que le code avec une course de données « fonctionnera correctement » si vous testez sur votre propre ordinateur. Ce n'est pas surprenant ... parfois ça va marcher, parfois ça ne marchera pas. Peut-être que cela fonctionnera toujours sur votre ordinateur et explosera sur l'ordinateur de quelqu'un d'autre. Mieux vaut faire les choses correctement avec la synchronisation des threads, juste tester n'est pas assez bon.

1

Possible, oui absolument.

Cependant, cela n'est jamais nécessaire. Il y a de bonnes primitives de synchronisation disponibles dans GLsync et glFinish et vous n'avez aucune raison de ne pas les utiliser.

Les effets exacts de la course de données ne sont pas spécifiés. Vous pouvez finir par lire une demi-texture, vous pouvez invoquer une erreur fatale dans le pilote, ou peut-être s'arrêtera-t-il.