IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

CUDA Discussion :

Exemple simple qui ne marche pas :(


Sujet :

CUDA

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 15
    Points : 4
    Points
    4
    Par défaut Exemple simple qui ne marche pas :(
    Bonjour @ tous ,

    j'ai vraiment besoin de votre aide.

    J'essaie de faire un programme qui fait de la logique de base sur un objet nommé "signal".
    Ce signal a deux valeurs, une à un cycle n (t0) et une seconde pour le cycle suivant (t1)

    Mon problème est que je ne parviens pas à mettre à jour correctement: l'appel de la fonction maj() fait t0=t1;

    Seulement, ce changement n'est tout simplement pas visible.


    Je vous laisse voir le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <cuda.h>
    #include <cuda_runtime.h>
     
     
    class  signal
    {
        bool _t0,_t1;
      public:
        __device__
        signal()
        {
        }
        __device__
        void init(bool valeur)
        {
          _t0=valeur;
          _t1=valeur;
        }
        __device__
        bool t1()
        {
          return _t1;
        }
        __device__
        bool t0()
        {
          return _t0;
        }
     
        __device__
        void w(bool val)
        {
          _t1=val;
        }
     
        __device__
        void maj()
        {
          _t0=_t1;
        threadfence();
        };
    };
     
     
     
    __global__
    void kernel(int n_cycles,int t_cycle,int* retour)
    {
        signal s;
        s.init(true);
        int i;
      for(i=0;i<n_cycles;i++)
      {
        retour[t_cycle*i]=i;
        retour[t_cycle*i+1]=s.t0();
        retour[t_cycle*i+2]=s.t1();
        retour[t_cycle*i+3]=~s.t0();
        s.w(~s.t0());
        threadfence();
        retour[t_cycle*i+4]=s.t1();
        s.maj();
        threadfence();
     
      }
    }
     
     
    //============================================================host
     
     
     
    int main()
    {
      int t_num_cycle	=1;
      int t_cycle		=4+t_num_cycle;
      int n_cycles		=100000/t_cycle;
      int t_buffer		=t_cycle*n_cycles;
      int t_bytes_buffer	=t_buffer*sizeof(int);
     
     
      FILE* pFile;
      pFile = fopen ("simu2.trace","w");
     
      int retour[t_buffer];
      int* retour_device;
     
      cudaFuncSetCacheConfig(kernel, cudaFuncCachePreferL1);
     
      CUevent start, stop;
     
      cudaEventCreate(&start);
      cudaEventCreate(&stop);
     
     
     
        cudaMalloc ( (void**) &retour_device, t_bytes_buffer);
     
        cudaEventRecord(start, 0);
     
     
        kernel<<<1,100>>>(n_cycles,t_cycle,retour_device);
     
        cudaThreadSynchronize();
        cudaMemcpy(retour,retour_device,t_bytes_buffer,cudaMemcpyDeviceToHost);
        cudaEventRecord(stop, 0);
      int j;
        for(j=0;j<n_cycles;j++)
        {
          fprintf (pFile, "cycle %5i   t0:%i    t1:%i    ~t0:%i    t1=~t0:%i \n",retour[j*t_cycle],retour[j*t_cycle+1],retour[j*t_cycle+2],retour[j*t_cycle+3],retour[j*t_cycle+4]);
     }
       fclose (pFile);
     
     
     
    cudaEventSynchronize(stop);
    float elapsedTime;
    cudaEventElapsedTime(&elapsedTime, start, stop);
    printf("===> %f  ms",elapsedTime);
      printf("\nnombre de cycles: %i \ntaille d'un cycle: %i \ntaille du buffer en int: %i \ntaille du buffer en octets: %i \n" ,n_cycles,t_cycle,t_buffer,t_bytes_buffer);
        return 0;
    }

    ...ainsi que la trace laissée (on voit bien que la dernière colonne ne correspond pas à ce qui est attentu:
    cycle 0 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 1 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 2 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 3 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 4 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 5 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 6 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 7 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 8 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 9 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 10 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 11 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 12 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 13 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 14 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 15 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 16 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 17 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 18 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 19 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 20 t0:1 t1:1 ~t0:-2 t1=~t0:1

  2. #2
    Membre régulier
    Inscrit en
    Août 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 68
    Points : 79
    Points
    79
    Par défaut
    Salut,

    Avant d'aller chercher le bug plus loin, pourquoi mets-tu des "threadfence" un peu partout ?
    Quel est la différence de comportement auquel tu t'attends avec et sans ?

  3. #3
    Membre régulier
    Inscrit en
    Août 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 68
    Points : 79
    Points
    79
    Par défaut
    Rien d'autre ne te choque dans la trace ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool a = true;
    cout << ~a << endl;

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 15
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par kiluak Voir le message
    Salut,

    Avant d'aller chercher le bug plus loin, pourquoi mets-tu des "threadfence" un peu partout ?
    Quel est la différence de comportement auquel tu t'attends avec et sans ?
    Bonjour kiluak

    D'après la doc, cette fonction permet de notifier à tous les threads que des changements ont été opérés sur des données. Voyant que ça ne marchait pas sans, j'ai voulu voir si le problème venait de là sans obtenir quoi que ce soit de mieux

    Citation Envoyé par kiluak Voir le message
    Rien d'autre ne te choque dans la trace ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool a = true;
    cout << ~a << endl;
    Franchment je ne vois pas ce que tu veux dire...

  5. #5
    Membre régulier
    Inscrit en
    Août 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 68
    Points : 79
    Points
    79
    Par défaut
    Citation Envoyé par fdocteur Voir le message
    D'après la doc, cette fonction permet de notifier à tous les threads que des changements ont été opérés sur des données. Voyant que ça ne marchait pas sans, j'ai voulu voir si le problème venait de là sans obtenir quoi que ce soit de mieux
    Je m'attendais à une explication comme celle là
    Ici les threadfence sont inutiles. En pratique, tu te serviras très peu de cette fonction, et il vaut mieux ne pas avoir à s'en servir vu les trucs zarbis qu'on doit écrire pour en avoir besoin

    La seule fonction de synchro que tu risques d'utiliser pendant un bon bout de temps, c'est __syncthreads(). Et ici, tu n'en as pas besoin non plus.

    Citation Envoyé par fdocteur Voir le message
    Franchment je ne vois pas ce que tu veux dire...
    Execute ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    #include <iostream>
     
    int main(void) {
        bool a = true;
        bool b = ~a;
        std::cout << "a = true" << std::endl;
     
        if(b)
            std::cout << "~a = true" << std::endl;
        else
            std::cout << "~a = false" << std::endl;
     
        return 0;
    }
    et dis moi si ça affiche bien ce à quoi tu t'attendais !

  6. #6
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Points : 662
    Points
    662
    Par défaut
    En fait pour te convaincre encore plus il faut regarder la taille du type bool, si je dis pas de bêtise ça doit être la même taille qu'un int, soit 4 octets.
    Donc true = 1 soit 0000 0000 0000 0000 0000 0000 0000 0001 et maintenant fait le complément à 1 de ça, tu verras que tu n'obtiendras pas 0 si c'est bien ça que tu cherche.
    Regarde plutôt du côté d'un décalage (>>).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    #include <iostream>
     
    typedef unsigned int uint;
     
    int main(void) {
        uint a = true;
        uint b = ~a;
        std::cout << "a = true" << std::endl;
     
        if(b)
            std::cout << "~a = true = " << b << std::endl;
        else
            std::cout << "~a = false = " << b << std::endl;
     
        return 0;
    }
    J'ai fait avec un unsigned int mais pour l'exemple ça revient au même.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    21:38 nicolas@nicolas-desktop ~/Bureau% ./test                    
    a = true
    ~a = true = 4294967294
    Tu vois qu'on est loin d'obtenir 0.

  7. #7
    Membre régulier
    Inscrit en
    Août 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 68
    Points : 79
    Points
    79
    Par défaut
    Néanmoins, je pense que tu devrais arrêter de penser d'abord en séquentiel !
    Cela n'apporte rien de coder en séquentiel en CUDA, car au final tu vas tout entièrement recoder, en ajoutant les accès mémoires, les synchros... Tout ce que tu gagnes, c'est quelques heures de debugging en plus pour un code qui n'a à priori pas d'intérêt

    De plus l'architecture de tes classes risques d'être fortement dépendante de la structure de tes algos (séquentiel/parallèle), pour moi tu perds ton temps !
    (sans vouloir te brusquer hein, c'est toi qui choisis après tout )

  8. #8
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Points : 662
    Points
    662
    Par défaut
    C'est clair que si tu veux coder sur un GPU, il faut revoir sa façon de penser et le faire le plus rapidement possible pour pouvoir jongler entre les deux CPU et GPU. Si tu t'obstines a faire du séquentiel cela risque d'être assez problématique, vaut mieux comme dit plus haut directement penser de la "bonne" façon.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 15
    Points : 4
    Points
    4
    Par défaut
    Tout d'abord, un grand merci pour réponses

    Pour le complément à 1 de 0, je suis d'accord que ça donne 0xFFFFFFFF = -1 mais ce n'est pas ça le problème en fait...

    En fait j'obtiens cecci:
    cycle 0 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 1 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 2 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 3 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 4 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 5 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 6 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 7 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 8 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 9 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 10 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 11 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 12 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 13 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 14 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 15 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 16 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 17 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 18 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 19 t0:1 t1:1 ~t0:-2 t1=~t0:1
    cycle 20 t0:1 t1:1 ~t0:-2 t1=~t0:1
    Alors que je devrais obtenir cela: (t1 prend not de t0 à chaque cycle, puis recopie de t1 dans t0)
    cycle 0 t0:1 t1:1 ~t0:-2 t1=~t0:-2
    cycle 1 t0:-2 t1:-2 ~t0:1 t1=~t0:1
    cycle 2 t0:1 t1:1 ~t0:-2 t1=~t0:-2
    cycle 3 t0:-2 t1:-2~t0:-2 t1=~t0:1
    cycle 4 t0:1 t1:1 ~t0:-2 t1=~t0:-2
    cycle 5 t0:-2 t1:-2 ~t0:1 t1=~t0:1

    ...
    etc
    ...
    Donc le passage d'un cycle à un autre (fonction maj() ) ne se fait pas correctement: le t0=t1 est comme invisible

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 15
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par AuraHxC Voir le message
    C'est clair que si tu veux coder sur un GPU, il faut revoir sa façon de penser et le faire le plus rapidement possible pour pouvoir jongler entre les deux CPU et GPU. Si tu t'obstines a faire du séquentiel cela risque d'être assez problématique, vaut mieux comme dit plus haut directement penser de la "bonne" façon.
    En fait je présente des codes simples en séquentiel pour pas que ce soit trop indigeste (mon code l'est assez!)

    Sinon, dans mon vrai code, j'ai du parallèle dans tous les sens. C'est lorsque je me heurte à un souci que je repasse sur quelque chose de béta en séquentiel juste pour tenter de résoudre le souci

  11. #11
    Membre régulier
    Inscrit en
    Août 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 68
    Points : 79
    Points
    79
    Par défaut
    Tu utilises tes bool comme des int, tu as donc des conversions implicites un peu partout !
    Tu es entre autre sujet au paragraphe "Integral conversions" de la norme C++.

    Dans ton cas, ~1 = -2 = 1, il n'y a pas de souci.
    Puisque tes bool ne sont pas utilisés comme des bools, je te suggère de mettre de l'int" partout sinon tu risques de tourner en rond longtemps

  12. #12
    Membre régulier
    Inscrit en
    Août 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 68
    Points : 79
    Points
    79
    Par défaut
    Citation Envoyé par fdocteur Voir le message
    Sinon, dans mon vrai code, j'ai du parallèle dans tous les sens. C'est lorsque je me heurte à un souci que je repasse sur quelque chose de béta en séquentiel juste pour tenter de résoudre le souci
    Conseil : apprends à débugguer directement en CUDA tu gagnera des heures !
    (printf marche dans du CUDA su tu as un toolkit pas trop ancien)

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 15
    Points : 4
    Points
    4
    Par défaut
    J'ai suivi vos conseils et au lieu de faire du not sur du booléen, j'ai fait du ......-1: ça marche!
    Je n'en reviens pas d'être rester comme un c** coincé là-dessus!

    Merci à tous les deux et chapeau bas!

Discussions similaires

  1. un programme trop simple qui ne marche pas
    Par smp82 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 27/10/2008, 15h46
  2. [RegEx] regex simple qui ne marche pas (encore)
    Par denisvignes dans le forum Langage
    Réponses: 5
    Dernier message: 19/09/2008, 15h04
  3. Programme super simple qui ne marche pas!
    Par _Michel dans le forum Visual C++
    Réponses: 2
    Dernier message: 07/01/2008, 18h50
  4. Script tout simple qui ne marche pas sous IE
    Par Bleuarff dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 14/02/2007, 18h48
  5. suivi de session simple qui ne marche pas
    Par mikebranque dans le forum Langage
    Réponses: 6
    Dernier message: 02/06/2006, 16h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo