0
votes

Comparaison GPU lente dans le gifle

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: % 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>

J'essaie de trouver un moyen plus rapide de faire cette opération. P>

Merci! P>

Modifier pour clarification forte> p>

Mon code est quelque chose comme: p> xxx pré>

et il semble que le goulot d'étranglement de ce code (Pour ce 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>


2 commentaires

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.


3 Réponses :


0
votes

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


0 commentaires

7
votes

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.

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.


9 commentaires

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") . Pour ce processus, le goulot d'étranglement est en fait le si 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 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 et non du si , 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 ? Est-ce que même quelque chose sur un GPU?



0
votes

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

Il y a aussi une fonction plus grande que vous pourriez utiliser pour effectuer la comparaison dans le GPU

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.


0 commentaires