2010-06-24 6 views
2

Je suis en train de concevoir une application CUDA pour traiter certaines vidéos. L'algorithme que j'utilise appelle à remplir des pixels vides d'une manière qui n'est pas sans rappeler le jeu de vie de Conway: si les pixels autour d'un autre pixel sont tous remplis et toutes les valeurs similaires, le pixel spécifique est rempli avec la valeur environnante. Cela se répète jusqu'à ce que tout le nombre de pixels à corriger soit égal au nombre de pixels à corriger lors de la dernière itération (c'est-à-dire quand rien d'autre ne peut être fait).Algorithme massivement parallèle pour propager les pixels

Mon problème est le suivant: la partie précédente et la partie suivante du pipeline de traitement sont implémentées en CUDA sur le GPU. Il serait coûteux de transférer l'intégralité de l'image dans la RAM, de la traiter sur le CPU, puis de la renvoyer au GPU. Même si c'est plus lent, je voudrais implémenter l'algorithme dans CUDA. Cependant, la nature de ce problème nécessite la synchronisation entre tous les threads pour mettre à jour l'image globale entre chaque itération. J'ai pensé à appeler le noyau à chaque fois plusieurs fois, mais je ne peux pas déterminer quand le processus est terminé, sauf si je transfère les données au processeur entre chaque itération, ce qui entraînerait une grande inefficacité en raison de la latence du transfert de mémoire. Interface PCI-e.

Est-ce que quelqu'un avec une certaine expérience avec des algorithmes parallèles a des suggestions? Merci d'avance.

Répondre

2

Il semble que vous ayez besoin d'un tampon d'image supplémentaire, de sorte que vous puissiez conserver l'image d'entrée non modifiée dans un tampon et écrire l'image de sortie traitée dans le second tampon. De cette façon, chaque thread peut traiter un seul pixel de sortie (ou un petit bloc de pixels de sortie) sans se soucier de la synchronisation, etc.

+0

Merci pour la réponse Paul. Je ne pense pas avoir été trop clair sur l'algorithme, mais mon problème vient du fait que j'ai besoin d'itérer ce processus. La première itération remplirait certains pixels, alors la deuxième itération devrait lire les résultats du premier et remplir quelques pixels de plus qui n'auraient pas pu être remplis dans la première itération. Le besoin de synchronisation vient de mon besoin de connaître les résultats de tous les pixels environnants avant de traiter le pixel lui-même. – Xzhsh

+0

OK - mais ne pouvez-vous pas le faire avec deux tampons et basculer en arrière et en avant? A -> B -> A -> B -> ...? Si ce n'est pas le cas, nous devrions peut-être voir plus de détails sur l'algorithme actuel. –

+0

Il pourrait être implémenté comme ça, si seulement CUDA permettait une certaine synchronisation entre les blocs de threads. Fondamentalement, la 2ème étape dépend du 1er et la 3ème dépend du 2ème. Je peux seulement synchroniser entre les threads à l'intérieur d'un bloc de threads (512 threads maximum). Sans beaucoup de blocs de threads, je ne profite pas du parallélisme de CUDA, mais avec beaucoup de blocs de threads, je n'ai aucun moyen de garantir que chacun finira avant d'itérer sauf en appelant le noyau plusieurs fois. Et si je veux appeler le noyau plusieurs fois, je dois transférer les données à la CPU pour vérifier si c'est fait. : | – Xzhsh

Questions connexes