Je suis débutant avec Opencl et j'ai des difficultés à comprendre quelque chose. Je veux améliorer les transferts d'une image entre hôte et appareil. J'ai fait un schéma pour mieux me comprendre. P>
p>
TOP: Qu'est-ce que j'ai maintenant | Bottom: ce que je veux HTD (hôte à périphérique) et DTH (périphérique à héberger) sont des transferts de mémoire. K1 et K2 sont des noyaux. P>
J'ai pensé à utiliser la mémoire de mappage, mais le premier transfert (hôte à l'appareil) est effectué avec la commande CLSETKERNARG (), non? Ou dois-je couper mon image d'entrée en sous-image et utiliser la mappage pour obtenir l'image de sortie? P>
Merci. P>
Edit: Plus d'informations P>
K1 Process Mem Image d'entrée. K2 Process Sortie Image de K1. P>
Donc, je veux transférer Meminput en plusieurs morceaux pour K1. Et je veux lire et enregistrer sur l'hôte le mémo traité par K2. P>
4 Réponses :
Comme vous l'avez peut-être déjà vu, vous effectuez un transfert d'hôte au périphérique à l'aide de toutes les commandes ayant le mot-clé "Enqueue" en eux ont une propriété spéciale: Les commandes ne sont pas exécutées directement, mais lorsque vous les tienchez à l'aide de Cela signifie que toutes les actions se produisent à la fois et que vous devez la synchroniser à l'aide des objets d'événement. Comme tout (mai) se produit à la fois, vous pouvez faire quelque chose comme ceci (chaque point se produit en même temps): p> N'oubliez pas: Enqueuning Tâches sans événement peut entraîner une exécution simultanée de tous les éléments en profondeur! p> pour vous assurer que les données de processus B ne se produisent pas avant le transfert B, vous avez pour récupérer un objet d'événement à partir de au lieu de fournir null, chaque commande peut bien sûr attendre sur certains objets et générer un nouvel objet d'événement. Le paramètre à côté du dernier est un tableau, vous pouvez donc faire l'événement attendre plusieurs événements! P> p>
EDIT: Résumez les commentaires ci-dessous
Transférer des données strong> - Quelle commande agit là où? p> * Vous pouvez initialiser le tampon directement en fournissant des données à l'aide du clenqueuewritebuffer code> et similaire. clfininish code>, clflush code>, clenqueuewaitorevents code>, utilisant clenqueuewritebuffer code> Mode de blocage et d'autres autres. P>
clenqueuewritebuffer code> et l'approvisionnement en tant qu'objet à attendre clenqueuendrangekernel code> p>
host_ptr code> paramètre. p> p>
D'accord. Mais mon problème est le transfert d'un tampon (une image 2D dans mon cas). Un exemple: sur mon hôte, j'ai un tampon qui représente un éventail de 100 éléments. Mais je veux envoyer 10 éléments à la fois sur l'appareil et une fois terminé, je suis d'accord, je synchonne de démarrer mon noyau. Je veux éviter le transfert complet du tampon au début (voir le schéma).
Deux des paramètres que je viens d'écrire, car les points peuvent recevoir une matrice de tailles, l'une définit la plage, l'autre définit le décalage de la zone que vous souhaitez copier. Je n'ai pas encore le doc disponible, mais je suppose que c'est exactement ce que vous voulez! ;)
Comme ceci: taille_t origine [] = {0,0,0}, région [] = {2,2,1}; clenqueuewrittimage (file d'attente, image, cl_false, origine, région, 0, 0, y votrehostdata, événements_to_wait_for, new_event) code> MAINTENEZ maintenant l'origine et appelez-la à nouveau. De cette façon, vous pouvez transférer des sous-ensembles de votre tampon. Assurez-vous également de compenser le pointeur sur YOURHOSTDATA code> de manière appropriée. (Remarque: l'origine et le décalage doivent être à 3 dimensions. région [2] code> doit être 1 code> pour une image 2D-2D
Stack Exchange vous notifie sur un commentaire que je ne peux pas voir ici. J'essaie d'interpréter l'aperçu de ma boîte de réception;) Si vous souhaitez transférer des données de l'hôte sur le périphérique ou inversement, vous utilisez clenqeeueuwrite ... code> ou clenqueuserAd ... code>. Si vous souhaitez transférer des données de l'intérieur de l'appareil vers un autre emplacement de l'appareil que vous utilisez clenqueuecopy ... code>
YourhostData ne peut pas être un objet cl_mem à partir d'une image précédente? J'ai une erreur quand un essai ça. Et comment je peux compenser ce pointeur? `error = clenqueuewrittimage (CommandQueue, INPUT_IMAGE, CL_TRUE, Origin1, Région1, Image_ROW_PITCH, Image_SLICE_PITCH, LOADED_IMAGE, 0, NULL, NULL); `Loaded_Image est une image CL_MEM-2D.
Je pense avoir du mal à comprendre comment utiliser le pointeur. Loaded_Image est un cl_mem où les données d'image sont et entrées_Image le cl_mem utilisé par les noyaux.
Vous ne pouvez pas manipuler les pointeurs d'objets CL, uniquement de tableaux de données hôtes! Si vous avez un cl_image et souhaitez le transférer sur un autre cl_image, vous devez utiliser clenqueucopyImage code>. Et là, vous ne compensez pas le pointeur, vous ne pouvez modifier que le paramètre d'origine et de région.
Peut-être devriez-vous affiner votre question, j'ai compris que vous avez une gamme de données dans votre zone de CPU et que vous souhaitez transférer la pièce par pièce au GPU, mais je comprends maintenant, comme si tout est déjà sur le GPU :)
Mais clenQueCopyImage code> transfert sur le périphérique sur le périphérique? Je comprends, je vais utiliser un tableau pour stocker des données avant de transférer sur le périphérique dans CL_MEM. Merci beaucoup !
Vous avez compris. Au début de mon programme, je charge une image de mon disque dur dans un cl_mem. Je veux juste transférer cette pièce CL_MEM image2D par pièce sur le GPU.
S'il est dans un cl_mem, il est déjà sur le GPU, car les objets CL_MEM sont toujours créés dans la mémoire de votre périphérique CL.
Ok je pense avoir trouvé. Donc, lorsque je crée l'image 2D sur mon hôte (à partir de données sur mon disque dur), je ne spécifie aucun indicateur. (1) Après avoir utilisé ClenQueCopyImage pour copier ce cl_mem à un autre sur mon GPU. Nvidia Visual Profiler Affiche ce que je veux (voir le bas de mon schéma).
Désolé, je ne comprends pas complètement ça. Mon flux de travail: - # - b> Lire l'image du disque dur sur [Entier | Char] -array - # - B> Créer un tampon sur GPU - # - B> Transfert Tableau au tampon (si nécessaire, vous pouvez le faire par éléments) - # - B> Travaillez avec elle.
CL_MEM sont toujours créés dans la mémoire de mon GPU? Ok ... je ne l'ai pas compris, je pensais que cela devait être fait explicitement (Clenqueue, Sekernelarg, etc ...)
Lorsque vous créez votre file d'attente de commande, vous devez activer l'exécution hors commande dans vos propriétés. Voir: cl_Queue_out_of_order_exec_mode_enable, CLCreatecommandQueue . < P> Cela vous permettra de configurer vos plus petites chaînes de tâches et de les relier. Tout cela est fait sur l'hôte. P>
pseudo-code hôte: p> Lorsque vous faites la queue des tâches, placez le précédent cl_event dans event_wait_list de chaque tâche. "Enqueuewredatafromhost" J'ai ci-dessus n'aurait pas à attendre qu'un autre événement commence. P> alternativement, p>
Beaucoup de plateformes Opencl ne prennent pas en charge les files d'attente de commandes hors commandes; La façon dont la plupart des fournisseurs disent à se chevaucher DMA et à calculer consiste à utiliser plusieurs files d'attente de commande (dans l'ordre). Vous pouvez utiliser des événements pour vous assurer que les dépendances sont effectuées dans le bon ordre. Nvidia a exemple de code qui montre la DMA chevauchée et le fait de le faire de cette façon (bien qu'il soit sous-optimal; il peut aller légèrement plus vite que ce qu'ils le disent). P>
Merci pour votre réponse. Dans mon cas, le calcul du noyau Opencl est court. Le transfert de données prend beaucoup de temps et c'est sur ce point que je veux gagner du temps. J'ai essayé cela sur un Nvidia GTX 260, mais cette carte graphique est incompatible avec les chevauchements de transfert / transfert de données (uniquement compatible avec le chevauchement de calcul / transfert de données). Dans NVIDIA OPENCL Meilleur Guide des pratiques, nous pouvons lire:> Les appareils NVIDIA avec capacités de calcul> = 2.0 Possédez 2 moteurs de copie indépendants et sont capables de copier simultané dans 2 directions simultanées avec le calcul du périphérique. Et la capacité de calcul GTX 260 Compute = 1.3 ...
Dithermaster Pourriez-vous indiquer un exemple de mise en œuvre de l'approche que vous mentionnez?
Voir «Exemple d'échantillon Copie / Compute Opencl» sur cette page: développeur.nvidia.com/opencl
La manière appropriée (comme je le fais et fonctionne parfaitement) consiste à créer 2 files d'attente de commande, une pour les E / S et une autre pour le traitement. Les deux doivent être dans le même contexte. P>
Vous pouvez utiliser des événements pour contrôler le calendrier des deux files d'attente et les opérations s'exécuteront en parallèle (si elles peuvent). Même si l'appareil ne prend pas en charge OutofOrderQueue, il fonctionne effectivement. P>
Par exemple, vous pouvez en faire ensemble toutes les 100 images de la file d'attente d'E / S au GPU et obtenir leurs événements. Ensuite, définissez ces événements comme la gâchette pour les noyaux. Et le transfert DTOH est déclenché par les événements du noyau. Même si vous en faisiez tous ces emplois à la fois, ils seront traités dans l'ordre et avec des E / S parallèles. P>
+1 pour le processus que vous avez utilisé pour faire le diagramme :)