2017-01-06 3 views
0

J'ai deux programmes écrits par moi à partir de zéro, l'un est une multiplication matricielle-matricielle. Lorsque j'exécutais les deux programmes avec des cartes GPU, et que je définissais la taille globale à 1024, je m'attendais à ce que le code du noyau s'exécute 1024 fois, et il était correct, il s'exécutait le même nombre de fois que la taille globale n'a pas d'importance pour coder les résultats et pour produire. Le même code que j'ai essayé d'exécuter avec le CPU, et j'ai été choqué quand j'ai vu que la fonction du noyau n'exécutait pas le même nombre de fois que la taille globale était définie. Voici l'exemple de integral: taille globale = 2048, taille locale = 1, Je m'attends à 2048 exécutions de la fonction du noyau, et oui, c'est 2048, mais quand nous avons la taille globale = 2048 et la taille locale = 16 alors il s'exécute 256 fois ... Est-ce normal? Pourquoi travailler avec CPU est-il différent dans openCl qu'avec GPU? Je pensais que ce n'est pas grave pour l'utilisateur quel appareil nous utilisons, le même code devrait fonctionner de la même manière sur différents appareils. Est-ce que je me trompe?OpenCL les mêmes algorithmes pour GPU et CPU mais OpenCl fonctionne différemment pour ces deux périphériques

Merci d'avance pour l'aide!

+0

Nous avons besoin d'un [exemple minimal, compilable, vérifiable] (http://stackoverflow.com/help/mcve) du problème. En général, le pilote est censé s'assurer que la grille entière est exécutée, c'est-à-dire la taille de travail locale fois que les threads de taille globale de travail s'exécutent globalement. – einpoklum

+0

Il doit y avoir une mauvaise interception de l'ID de thread global et de l'ID de groupe et de l'ID de thread local. Comment vérifiez-vous le nombre d'exécutions? –

+0

@huseyintugrulbuyukisik Je viens d'ajouter simplement + = 1 à la variable globale dans le code du noyau pour voir combien de fois le noyau a été exécuté – Gzyniu

Répondre

0

Utiliser des opérations atomiques pour les travaux en série (ou au moins difficilement réductibles). Pour compter le nombre de threads pris part, ne pas utiliser a[0]+=1;

atomic_add(&a[0],1); 

devrait fonctionner ou mieux encore

atomic_inc(a) 

où a est un entier non signé signé n'a pas d'importance.

+0

ok, oui, atomic_inc ne fonctionne pas plus vite. Je veux dire qu'il fait son travail, en augmentant la valeur mais cette valeur est différente de la taille globale à la fin. Je ne comprends pas, j'ai un code qui fonctionne parfaitement sur 1, 2 ou même 8 gpu mais quand je suis passé au CPU (je n'ai pas oublié de changer l'argument clgetDeviceIds à CL_DEVICE_TYPE_CPU) il agit étrangement ... différentes valeurs que sur GPU. Y a-t-il quelque chose de différent à propos du travail avec les processeurs au lieu des GPU? – Gzyniu

+0

J'ai résolu le problème avec des résultats différents mais j'ai toujours un problème avec le CPU et le GPU qui fonctionnent différemment. J'ai implémenté l'intégrale dans le noyau de cette façon: nous avons int id = get_global_id (0) et même si nous définissons une taille globale extrêmement grande, chaque thread aura plus de travail à faire, mais sur CPU, je vois que local_size = 4096 (c'est max) dans le noyau j'ai des threads numérotés de 0 à 4095 ... pourquoi?Je récupère l'identifiant global non local ... dans GPU il fonctionnait quand la taille locale était fixée à 1 et à 1024 et aucun problème vu. Pourquoi donc? – Gzyniu

+0

id commence à partir de 0 –

0

J'ai trouvé la source du problème. C'était à cause de la faible précision du flotteur, quand j'ai changé les variables pour doubler cela fonctionne très bien. J'ai lu quelque part que CPU et GPU en termes d'opérations en virgule flottante, travail légèrement différent en ce qui concerne la précision.