Je veux tester à l'aide d'un tampon si un flotteur est positif, E.G.:
import cupy as cp
n = 100000
X = cp.random.randn(n) # can be greater
for _ in range(100): # There may be more iterations
result = X.dot(X)
if result < 1.2:
break
p>my problème est que cette opération est extrêmement lente:
J'essaie de trouver un moyen plus rapide de faire cette opération. P> Merci! P> Mon code est quelque chose comme: p> et il semble que le goulot d'étranglement de ce code (Pour ce % TimeIt U donne 26 micro secondes sur mon ordinateur. Ce sont des ordres de grandeur supérieurs à ce que je reçois dans la CPU. Je soupçonne que c'est parce que tu dois être jeté sur la CPU ... p> n code>) est l'évaluation du résultat . C'est encore beaucoup plus rapide que sur la CPU depuis le dot code> coûte moins. P> p>
3 Réponses :
Cela peut être parce que, lors de l'utilisation de CUDA, le tableau doit être copié sur le GPU avant le traitement. Par conséquent, si votre matrice n'a qu'un seul élément, il peut être plus lent dans le GPU que dans la CPU. Vous devriez essayer un tableau plus grand et voir si cela continue à se produire p>
Exécution d'une seule opération sur le GPU est toujours une mauvaise idée. Pour obtenir des gains de performance hors de votre GPU, vous devez réaliser une bonne "intensité de calcul"; c'est-à-dire la quantité de calcul effectuée par rapport au mouvement de la mémoire; Soit de la RAM globale au GPU MEM ou du GPU MEM dans les noyaux eux-mêmes. Si vous n'avez pas au moins quelques tongs Hunderd par octet d'intensité de calcul, vous pouvez oublier en toute sécurité de réaliser toute vitesse sur le GPU. Cela dit que votre problème peut se prêter à l'accélération GPU, mais vous ne pouvez certainement pas comparer des déclarations comme celle-ci isolément de manière significative. P>
Mais même si votre algorithme consiste à enchaîner un certain nombre de telles opérations d'intensité de calction basse à faible calcul sur le GPU, vous serez toujours déçu par la vitesse de vitesse. Votre goulot d'étranglement sera votre bande passante de la mémoire GPU; Ce qui n'est vraiment pas aussi génial comparé à la bande passante de la mémoire de la CPU, car il peut regarder sur papier. Sauf si vous écrivez vos propres noyaux incorporels-intenses ou que vous envisagez de gérer de gros FFTS ou de telles utilisations avec SUPPY, ne pensez pas que cela vous donnera des économies d'argent-balle en portant simplement votre code numpy. P>
Mon code ressemble à ce qui suit: x = cp.random.randn (int (1e5)); résultat = x.dot (x); Si vous résulte <1.: Imprimer ("succès") code>. Pour ce processus, le goulot d'étranglement est en fait le si code> partie est vraiment frustrant. Je me demande comment déployer cela.
La quantité de travail impliquée ici ne vaut certainement pas la peine de gêner le GPU. Les frais généraux d'appeler le noyau vont de loin dépasser le temps de l'exécuter sur la CPU
Merci de votre aide. Je l'ai testé, le code que j'ai à l'aide de GPU est beaucoup plus rapide que d'utiliser la CPU. Mais le goulot d'étranglement dans le GPU est la comparaison d'un seul flotteur, qui est frustrant. J'ai édité mon message original avec un exemple.
Vous avez également ajouté un autre zéro à la taille de la matrice, qui la met en effet (marginalement) dans un territoire d'accélération du GPU potentiel. Mais vous n'avez probablement pas comparuré ce que vous pensez que vous avez fait. J'imagine que Dot revient immédiatement; et seule la copie implicite de la CPU à la CPU par la déclaration IF déclenche un appel de blocage pour attendre que le GPU renverse quelque chose.
Je suis désolé, j'essaie de donner un exemple minimal qui souligne clairement mon problème. C'est simple: mon code dans le GPU est beaucoup plus rapide que mon code sans GPU. Cependant, dans GPU, le goulot d'étranglement est le si code> instruction. Non, les points ne reviennent pas immédiatement, je la vérifie.
L'appel à DOT ne retournerait pas «immédiatement» bien sûr; La surcharge de fabrication d'un appel GPU est tout simplement substantielle par elle-même. Mais la documentation précise-t-elle s'il s'agit d'un appel de blocage ou de non bloquant? Je ne peux pas le trouver rapidement moi-même. Habituellement dans les scripts GPU, vous passez ces opérations au flux par défaut de manière non bloquante. Tout moyen facile d'obtenir une réponse définitive est de jouer avec la taille de la matrice par quelques ordres de grandeur. Si le point n'est pas bloqué cela ne devrait pas avoir d'importance pour vos horaires de points; Mais cela importera pour votre "chronométrage de si".
Merci, c'est ce que j'ai essayé et modifier la taille de x modifie le calendrier du dot code> et non du si code>, indiquant qu'il s'agit d'un appel de blocage si je Obtenez-le bien.
Ensuite, la seule chose à considérer est le "transfert de données" à la CPU; ou plutôt les frais généraux, parce que c'est un seul élément d'élément. Essayez de télécharger un seul élément au GPU; Cela devrait prendre à peu près au même moment que la copie d'un dos. Si cela prend plus de temps que cela, ID Dites au fichier un bugReport avec SPUPY.
Imprimer CODE>? Est-ce que même quelque chose sur un GPU?
Je pense que le problème ici est votre simple exploitation d'un périphérique GPU. Considérons en utilisant Dites 100 pour effectuer tous les calculs en parallèle (bien que dans le cas de votre code d'exemple simple, il ne faudrait que faire une fois). https://docs-crupy.chainer.org/fr/stable/ Tutoriel / Basic.html P>
Il y a aussi une fonction plus grande que vous pourriez utiliser pour effectuer la comparaison dans le GPU P>
La première fois que le point est appelé la fonction du noyau devra être compilé pour le GPU qui prendra beaucoup plus longtemps que les appels ultérieurs. P>
le résultat aura la même valeur dans chaque cycle de la boucle; et probablement sera toujours faux. Est-ce que ce comportement prévu?
C'est juste un exemple d'avoir les ordres de grandeur corrects, le code actuel fait en réalité quelque chose de plus significatif.