2011-10-13 4 views
6

Je développe actuellement une application OpenCL-pour un ensemble très hétérogène d'ordinateurs (en utilisant JavaCL pour être précis). Afin de maximiser les performances, je veux utiliser un GPU s'il est disponible sinon je veux revenir à la CPU et utiliser les instructions SIMD. Mon plan est d'implémenter le code OpenCL en utilisant des vector-types car je crois comprendre que cela permet aux processeurs de vectoriser les instructions et d'utiliser les instructions SIMD.la distribution OpenCL

Ma question est cependant en ce qui concerne la mise en œuvre qui OpenCL à utiliser. Par exemple. Si l'ordinateur a un GPU Nvidia, je suppose qu'il est préférable d'utiliser la bibliothèque de Nvidia mais si aucune GPU n'est disponible, je veux utiliser la bibliothèque d'Intel pour utiliser les instructions SIMD.

Comment puis-je y parvenir? Est-ce géré automatiquement ou dois-je inclure toutes les bibliothèques et implémenter une logique pour choisir la bonne? C'est comme si c'était un problème auquel plus de gens que moi.

Mise à jour Après avoir testé les différents pilotes OpenCL-ce est mon expérience jusqu'à présent:

  • Intel: écrasé la machine virtuelle Java quand JavaCL a essayé de l'appeler. Après un redémarrage, la JVM ne s'est pas écrasée, mais elle n'a pas non plus renvoyé de périphériques utilisables (j'utilisais un processeur Intel I7). Lorsque j'ai compilé le code OpenCL en mode hors connexion, il m'a semblé être capable de faire une auto-vectorisation , ce qui fait que le compilateur d'Intel semble plutôt sympa.

  • Nvidia: Refusé installer leurs pilotes WHQL car je n'ai pas revendiqué Nvidia ai-carte (cet ordinateur a une Geforce GT 330M). Quand je l'ai essayé sur un autre ordinateur j'ai réussi à obtenir tout le chemin à créer un noyau mais à la première exécution il a planté les pilotes (l'écran a clignoté pendant un moment et Windows 7 a dit qu'il devait redémarrer les pilotes) . La deuxième exécution a provoqué un écran bleu de décès.

  • AMD/ATI: Refusé installer SDK 32 bits (j'ai essayé depuis que je vais utiliser une machine virtuelle Java 32 bits), mais 64 bits SDK a bien fonctionné. C'est le seul pilote sur lequel j'ai réussi à exécuter le code (après un redémarrage car il a d'abord donné un message d'erreur cryptique lors de la compilation). Cependant, il ne semble pas être en mesure de faire aucune vectorisation implicite et puisque je n'ai pas de GPU ATI je n'ai pas eu de performance augmentation par rapport à l'implémentation Java. Si j'utilise des types vectoriels, je pourrais cependant voir quelques améliorations.

TL; DR Aucun des conducteurs semblent prêts pour un usage commercial. Je vais probablement créer un module JNI avec du code C compilé pour utiliser les instructions SSE.

Répondre

4

d'abord essayer de comprendre les hôtes & périphériques: http://www.streamcomputing.eu/blog/2011-07-14/basic-concept-hosts-and-devices/

Fondamentalement, vous pouvez simplement faire exactement ce que vous avez décrit: vérifier si un pilote est disponible et si non, essayez la suivante. Ce que vous choisissez en premier dépend entièrement de vos préférences. Je choisirais l'appareil sur lequel j'ai testé mon noyau le mieux. Dans JavaCL, vous pouvez choisir le périphérique le plus rapide avec JavaCL.createBestContext et CLPlatform.getBestDevice, vérifiez le code hôte ici: http://ochafik.com/blog/?p=501

Know NVidia ne supporte pas les processeurs via leur pilote; seulement AMD et Intel le font. Aussi est de cibler plusieurs périphériques (disons 2 GPUs et un CPU) un peu plus difficile.

2

Il n'y a pas d'API fournissant ce que vous voulez. Toutefois, vous pouvez effectuer les opérations suivantes:

Je vous suggère de parcourir les clGetPlatformIDs et d'interroger le nombre de périphériques (clGetDeviceIDs) et le type de périphérique pour chaque périphérique; et choisissez la plate-forme qui a les deux types. puis construire une carte dans le code u'r, qui mappe pour chaque type la liste des plates-formes qui le supportent, ordonnée d'une certaine manière. Enfin, il suffit d'obtenir le premier élément de la liste correspondant à CL_DEVICE_TYPE_CPU et le premier élément correspondant à CL_DEVICE_TYPE_GPU. si les deux résultats retournés sont égaux (platform_cpu == platform_gpu), choisissez-en un et utilisez-le pour les deux.

S'il y a une plate-forme supportant les deux, vous obtiendrez la correspondance comme avant puisque vous avez des listes de commandes. alors vous pouvez également faire l'équilibrage de charge si vous aimez sur une plate-forme simple, comme ce qu'Intel a.