2017-01-24 3 views
1

Le même programme OpenCL est compilé sur différents périphériques OpenCL, éventuellement sur des plates-formes différentes. Une file d'attente de commandes est créée pour chaque périphérique. Ainsi, par exemple, il peut y avoir deux files d'attente, une pour le processeur et une pour le processeur graphique.Utilisation de différentes files d'attente de commandes OpenCL à partir de plusieurs threads hôtes

Est-il possible d'appeler clEnqueueNDRangeKernel puis clEnqueueReadBuffer (blocage) sur les deux files d'attente de commande, à partir de différents threads hôtes (un pour chaque file d'attente de commande)?

Par exemple en utilisant OpenMP, avec une boucle comme

// queues_ contains command queues for different contexts, 
// each with one device on one platform (e.g. CPU and GPU) 
#pragma omp parallel for num_threads(2) schedule(dynamic) 
for(int i = 0; i < job_count; ++i) { 
    cl::CommandQueue& queue = queues_[omp_get_thread_num()]; 
    // queue is for one device on one platform 
    // euqueue kernel, and read buffer on queue 
} 

Cela pourrait diviser la liste des tâches en deux morceaux pour CPU et GPU. schedule(dynamic) ferait en sorte que l'ordonnancement s'adapte dynamiquement aux temps d'exécution des noyaux. Le code hôte passerait le plus de temps à attendre le noyau (dans l'appel clEnqueueReadBuffer de blocage.) Mais grâce au périphérique CPU, le CPU serait en train d'exécuter le noyau (en OpenCL), et en même temps attendrait le GPU pour finir (dans le code hôte).

+2

Pour votre question, la réponse est oui. – Dithermaster

+1

J'ai créé un ray tracer en temps réel qui a équilibré la charge entre deux GPUS et CPU. Je l'ai fait en créant un fil pour chaque périphérique avec leur propre contexte. J'ai utilisé pthreads pour cela (parce que je ne connaissais pas OpenMP à l'époque) mais je suppose qu'OpenMP fonctionnerait aussi bien. J'ai créé un contexte séparé car je n'avais pas de files d'attente séparées fonctionnant avec les GPU Nvidia à l'époque (OpenCL 1.1) et dans un forum Nvidia, quelqu'un à Nvidia recommandait de créer un contexte différent pour chaque périphérique ayant son propre thread. –

Répondre

1

Si les contextes sont différents aussi, ils fonctionnent indépendamment, même avec des applications 3D. En fonction de l'implémentation, deux contextes peuvent être préemptés ou ultra-threadés par les pilotes mais vous pouvez ajouter une synchronisation basée sur les événements entre les contextes de sorte qu'un élément de la file d'attente attend un achèvement dans la file d'attente. Si elles vivent dans le même contexte, vous pouvez effectuer une synchronisation implicite entre deux files d'attente avec des pilotes ou des manipulations apis performantes. L'utilisation de tous les noyaux de CPU pour un noyau lié à la mémoire ne permet pas de copier des matrices vers et à partir de GPU assez rapidement, sauf si vous utilisez l'accès direct à la mémoire lors de la copie qui libère l'instruction de copie. Si le cache est assez grand et assez rapide, il n'a peut-être pas besoin d'une telle chose.