2010-07-14 6 views

Répondre

2

En théorie oui, vous pouvez, l'API CL permet. Mais la plate-forme/implémentation doit le supporter, et je ne pense pas que la plupart des implémentations de CL le font. Pour ce faire, procurez-vous le cl_device_id de l'unité centrale et du périphérique GPU, et créez un contexte avec ces deux périphériques, en utilisant clCreateContext.

+1

Ou, sur les systèmes qui ne prennent pas en charge deux appareils dans une plate-forme, mais le processeur a une plate-forme et le GPU a une autre plate-forme, vous pouvez simplement diviser manuellement le travail entre les deux. Envoyez une partie du travail à la CPU et une partie du travail au GPU. –

1

Vous ne pouvez pas étendre un noyau à plusieurs périphériques. Mais si le code que vous utilisez n'est pas dépendant d'autres résultats (par exemple: traiter des blocs de 16 Ko de données, cela nécessite un traitement énorme), vous pouvez lancer le même noyau sur GPU et CPU. Et mettre des blocs sur le GPU et certains sur le CPU.

De cette façon, il devrait augmenter les performances.

Vous pouvez le faire en créant un clContext partagé pour le processeur et le GPU et 2 files d'attente de commandes.

Ceci n'est pas applicable à tous les noyaux. Parfois, le code du noyau s'applique à toutes les données d'entrée et ne peut pas être séparé en parties ou en morceaux.

+0

La mise en file d'attente des éléments de travail massifs est une mauvaise pratique. La raison en est que vous provoquerez la famine de workitem de rendu (provoquant des mises à jour d'écran léthargiques écoeurantes), ou pire, il y a un chien de garde qui avortera et rechargera le conducteur visuel (déclenchera la détection d'accrochage). Une pratique beaucoup mieux (quand c'est possible bien sûr) est d'avoir un flux de travail, mais n'obtient pas les résultats des éléments avant plusieurs après avoir été mis en file d'attente pour l'exécution. Cela vous permet de limiter l'utilisation du GPU pour ne pas surcharger le travail de dessin à l'écran. – doug65536

2

Un contexte ne peut être que pour une plate-forme. Si votre code multi-périphérique doit fonctionner sur plusieurs plates-formes (par exemple, plate-forme Intel OpenCL et NVidia GPU), vous avez besoin de contextes distincts. Cependant, si le GPU et le CPU se trouvent sur la même plate-forme, alors oui, vous pouvez utiliser un contexte.

Si vous utilisez plusieurs périphériques sur la même plate-forme (deux GPU identiques ou deux GPU du même fabricant), vous pouvez partager le contexte, à condition qu'ils proviennent tous deux d'un seul appel clGetDeviceIDs.

EDIT: Je dois ajouter qu'un contexte GPU + CPU ne signifie pas une exécution CPU + GPU gérée automatiquement. Généralement, il est recommandé de laisser le pilote allouer un tampon mémoire pouvant être mis en mémoire DMA par le GPU pour des performances maximales. Dans le cas où vous avez le processeur et le GPU dans le même contexte, vous seriez en mesure de partager ces tampons entre les deux appareils.

Vous devez encore diviser la charge de travail vous-même. Ma technique d'équilibrage de charge préférée utilise des événements. Chaque élément de travail n, attachez un objet événement à une commande (ou mettez en file d'attente un marqueur) et attendez l'événement que vous avez défini il y a des éléments de travail (le précédent). Si vous n'aviez pas à attendre, vous devez augmenter n sur cet appareil, si vous deviez attendre, vous devriez diminuer n. Cela limitera la profondeur de la file d'attente, n planera autour de la profondeur parfaite pour garder l'appareil occupé. Vous devez le faire de toute façon pour éviter de provoquer la famine du rendu GUI. Il suffit de garder n commandes dans chaque file d'attente de commande (où le CPU et le GPU ont n séparé) et il se divisera parfaitement.

Questions connexes