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 :

Calcul de la moyenne d un Tableau


Sujet :

CUDA

  1. #1
    Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Calcul de la moyenne d un Tableau
    Salut a tous!!

    Je suis debutant en CUDA, et pour m exercer afin de comprendre comment tout cela fonctionne, j ai essaye de calculer la moyenne d un tableau de donnes
    mais malheuresement je bug
    kelkun pourrait il m aider svp
    merci
    voici le code ke j ai essaye d ecrire
    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
     
     
     
    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"
     
    #include <stdio.h>
    #define anzahl 256
     
     
     
    __global__ void MittelWert(float *result,  float *elt)
    {
        int sum = 0 ;
    	int tid = threadIdx.x ;
    	for(int i =1 ; i<anzahl; i*=2)
    	{
    	   if(tid %(i*2) == 0 && tid+i<anzahl)
    	     {
    	   elt[tid] += elt[blockIdx.x*i+tid];
    	   sum+=elt[tid];
    	   printf("thread : %f\n",threadIdx.x);
    	      }
    		  __syncthreads();
    	}
    	sum/= anzahl;
    	result[tid] = sum ;
     
    }
     
     
     
     
    int main()
    {
     
    	int * dev_elt;
    	int * dev_result;
    	const float size = anzahl * anzahl * sizeof(float);
     
    	cudaMalloc( (void**) & dev_elt, size);
    	cudaMalloc( (void**) & dev_result, size);
     
    	cudaMemcpy(dev_elt, elt, size, cudaMemcpyHostToDevice) ;
     
    	MittelWert<<<1, anzahl>>>(dev_result, dev_elt);
     
    	cudaMemcpy(dev_result, result, size, cudaMemcpyDeviceToHost);
     
     
        cudaFree ( dev_elt );
        cudaFree ( dev_result );
     
     
    }

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour et bienvenue sur le forum

    Plusieurs remarques :
    - peux-tu éviter le style sms, merci
    - tu bug, c'est à dire ? Tu as un message d'erreur lors de la compilation ? Tu n'obtiens pas le résultat attendu ?
    - je n'ai pas essayé de comprendre comment tu veux faire pour calculer la moyenne mais peux tu expliquer l'algorithme que tu souhaites implémenter
    - dans ton main, je vois pas la déclaration de elt et result

  3. #3
    Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Salut gbdivers
    tout d abord je tiens á te remercier de ta reponse et ainsi que á m excuser, si j ai pas respecte les regles du forum ou aussi de la tenu de mon message

    - avec je bug: je voulais dire je ne recois rien apres la compilation
    - Mon but a moi c etait juste de calculer la moyenne d un tableau avec CUDA, pour voir comment tout ceci fonctionne, car j assimile mieux avec des ex concrets
    - Mon code n etant pas excellents, j aimerais donc savoir si quelqu' un pourrait me fournir un exple de code qui m aidera dans la comprehension

    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
     
     
    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"
     
    #include <stdio.h>
    #define anzahl 256
     
     
     
    __global__ void MittelWert(float *result,  float *elt)
    {
        int sum = 0 ;
    	int tid = threadIdx.x ;
    	for(int i =1 ; i<anzahl; i*=2)
    	{
    	   if(tid %(i*2) == 0 && tid+i<anzahl)
    	     {
    	   elt[tid] += elt[blockIdx.x*i+tid];
    	   sum+=elt[tid];
    	   printf("thread : %f\n",threadIdx.x);
    	      }
    		  __syncthreads();
    	}
    	sum/= anzahl;
    	result[tid] = sum ;
     
    }
     
     
     
     
    int main()
    {
            int * elt;
            int * result;
    	int * dev_elt;
    	int * dev_result;
    	const float size = anzahl * anzahl * sizeof(float);
     
    	cudaMalloc( (void**) & dev_elt, size);
    	cudaMalloc( (void**) & dev_result, size);
     
    	cudaMemcpy(dev_elt, elt, size, cudaMemcpyHostToDevice) ;
     
    	MittelWert<<<1, anzahl>>>(dev_result, dev_elt);
     
    	cudaMemcpy(dev_result, result, size, cudaMemcpyDeviceToHost);
     
     
        cudaFree ( dev_elt );
        cudaFree ( dev_result );
     
     
    }

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int * elt;
    int * result;
    Tu déclares mais n’initialises pas ces variables. C'est de la problématique de base en C. Tu connais le C aussi ou tu débutes ?
    Pourquoi result est un tableau ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const float size = anzahl * anzahl * sizeof(float);
    Ok, calcul de la taille de l'espace mémoire (en octets) que tu auras besoin pour ton tableau d'entrée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int * dev_elt;
    int * dev_result;
    cudaMalloc( (void**) & dev_elt, size);
    cudaMalloc( (void**) & dev_result, size);
    Ok, tu initialises ces variables.
    Tu comprends la différence entre les variables elt/result et dev_elt/dev_result ?
    Pourquoi dev_result est de la taille de ton tableau d'entrée ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cudaMemcpy(dev_elt, elt, size, cudaMemcpyHostToDevice) ;
    Ok, tu copies les "size" octects depuis ton tableau "elt" dans la RAM vers le tableau "dev_elt" dans le GPU. Sauf que tu n'as pas initialisé ton tableau "elt".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MittelWert<<<1, anzahl>>>(dev_result, dev_elt);
    Pourquoi pas ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    MittelWert<<<anzahl, 1>>>(dev_result, dev_elt);
    // ou 
    MittelWert<<<256, anzahl/256>>>(dev_result, dev_elt);
    // ou n'importe quelle taille intermédiaire ?
    MittelWert<<<128, anzahl/128>>>(dev_result, dev_elt);
    MittelWert<<<64, anzahl/64>>>(dev_result, dev_elt);
    MittelWert<<<32, anzahl/32>>>(dev_result, dev_elt);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cudaMemcpy(dev_result, result, size, cudaMemcpyDeviceToHost);
    Tu copies les "size" octets de "result" vers "dev_result" mais depuis le GPU vers la RAM... Perdu ! C'est l'inverse (c'est bien du GPU vers la RAM mais c'est de "dev_result" vers "result"). As tu regardé la définition de cette fonction pour comprendre les paramètres à utiliser ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cudaFree ( dev_elt );
    cudaFree ( dev_result );
    Ok

    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
    __global__ void MittelWert(float *result,  float *elt)
    {
        int sum = 0 ;
        int tid = threadIdx.x ;
        for(int i =1 ; i<anzahl; i*=2)
        {
            if(tid %(i*2) == 0 && tid+i<anzahl)
            {
                elt[tid] += elt[blockIdx.x*i+tid];
                sum+=elt[tid];
                printf("thread : %f\n",threadIdx.x);
            }
            __syncthreads();
        }
        sum/= anzahl;
        result[tid] = sum ;
    }
    Aie, ça fait mal aux yeux. Peux tu représenter par un schéma ce que tu souhaites utiliser comme algorithme ?
    Normalement, ce que tu souhaites faire tiens en 3-4 lignes. Donc là, il y a trop de chose inutiles (peut être).


    Tu suis un livre ou un cours en particulier sur CUDA ?

  5. #5
    Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Moyenne
    Hello gbdivers!

    suis super flatte que tu sois de bonnes humeurs, car a lire tes commentaires,
    il fallait vraiment avoir des nerfs solides et de la patience + de l humeur pour lire et comprendre mon code

    Non malheureusement je suis pas de cours particulier en CUDA, je me force de comprendre des Tutoriels online.

    J' espère t aurais garder ta bonne humeur et que tu continueras a me guider

    Merci encore
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // j ai declare result comme un tableau, car c ou je stockerai le resulat final
    int * result;
    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
     
     
    // Pourrai je donc simplifier la fonction __global__ void MittelWert() comme suivant?
    // car le but etant tjrs de calculer la moyenne du tableau
    __global__ void MittelWert(float *result,  float *elt)
    {
        int sum = 0 ;
        int tid = threadIdx.x ;
        for(int i =1 ; i<anzahl; i++)
        {
     
                elt[tid] += elt[blockIdx.x*i+tid];
                sum+=elt[tid];
     
        }
        sum/= anzahl;
        result[tid] = sum ;
    }

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour

    // j ai declare result comme un tableau, car c ou je stockerai le resulat final
    int * result;
    Sauf que ton résultat est bien un seul nombre (la moyenne), donc pas besoin de tableau

    C'est quoi ce nom de variable ???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    __global__ void MittelWert(float *result,  float *elt)
    Tu vas écrire dans result mais tu ne fais que lire elt, tu peux donc mettre elt en "const"

    Là, on voit que tu n'as pas encore assimilé la programmation parallèle
    Le code du kernel sera exécuté N fois, pour chaque élément du tableau. Si chaque élément initialise le compteur... ça marchera pas
    Il faut initialiser une seule fois, donc pas par les kernels mais par l'hôte

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int tid = threadIdx.x ;
    Ok, tu récupères le n° du kernel, qui correspond à la position d'une élément dans le tableau

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i =1 ; i<anzahl; i++)
    Et là, tu parcours tous les éléments du tableau...
    Ce n'est pas interdit ce que tu fais, cependant tu fais une boucle classique, comme tu le ferais dans un code C++. Tu perds donc l'intérêt du parallélisme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    elt[tid] += elt[blockIdx.x*i+tid];
    Mouais, là, je ne sais pas ce que tu fais...

    Ok, tu ajoutes l'élément "tid" à la somme. (malheureusement, à la ligne précédente, tu as écris dans cette variable et mis n'importe quoi dedans )

    Ok

    Pourquoi un tableau ?


    Je pense qu'il faut que tu prennes un papier et crayon et que tu mettes au propre ce que tu veux faire et comment tu veux faire.
    Il y a des problèmes de syntaxe CUDA , mais il y a aussi des problèmes de compréhension de l'algo parallèle

    suis super flatte que tu sois de bonnes humeurs, car a lire tes commentaires,
    il fallait vraiment avoir des nerfs solides et de la patience + de l humeur pour lire et comprendre mon code
    En fait, je suis jamais de mauvaise humeur C'était surtout pour que tu comprennes que les MP peuvent être très mal perçu

  7. #7
    Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bonjour

    une fois de plus j ai essaye d améliorer mon code et de mieux transmettre mon problème.
    comme énoncé:
    j ai un tableau v1 qui a 10000000 éléments
    et j aimerais calcule la moyenne de ce tableau avec CUDA

    en C, cela serai quelque choses comme ceci:
    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
     
    // dans un 1er temps j initialise le tableau
    int j ;
     
    for (j=0; j <10000000; j++)
    {
        tab[j]=j;
    }
     
    // ensuite je calcule la moyenne du tableau
    int i;
    int somme =0;
    int moy;
    for (i=0; i <10000000; i++)
    { somme +=tab[i];}
    moy /=10000000;
     
     
    #include <iostream>
    using std::cout;
    using std::endl;
     
    #include "gcc-4-7.h"
     
    struct Z {
        // ...
     
        Z(long long ii) : i(ii) {}    // can initialize with an long long
        Z(long) = delete; // but not anything less
     
        long long i;
    };
    donc j aimerais faire de même avec Cuda, mais je rencontre certaines difficultés qui sont expliquées dans mon code CUDA suivant:

    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
     
    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"
     
    #include <stdio.h>
     
    /*
    la fonction  MoyenneTab() est sensé calculer la moyenne du tableau v1 et l enregistrer dans le tableau res.
    la moyenne devrait se calculer comme suivant:
    1- addition parallèle de tous les premiers éléments de chaque bloc:
    1erélément du bloc0 + 1er élément du bloc1+...+ 1er élément du blocn = X
    2- ensuite le résultat divisé par le nombre de blocs = NB
    X/ NB = R
    3- et se résultat est ensuite stocke le tableau res 
     
    ceci est ce que j aimerais implémenter dans la fonction MoyenneTab() :(
    mon probleme est le suivant:
    - je ne sais pas comment distinguer les elements par bloc, c-ad:
    en C je sais que tab[i] = elemt i du tableau tab
    mais en CUDA je m embrouilles totalement avec les:
    blockDim.x, blockIdx.x, threadIdx.x; :(
     
    */
     
     
    __global__ void MoyenneTab( float* v1, float* res)
    {
        unsigned int i = blockDim.x * blockIdx.x + threadIdx.x;
        int sum = 0 ;
     
        if (i < 39063) sum+= v1[i];
     
        sum/= 39063;
        res[i]  = sum ;
    }
     
    int main()
    {
     
        unsigned int N = 10000000 // nombre d elements du tableau
                unsigned int i; 
     
        // declaration de l hote
        float *h_v1 = (float*) malloc( N*sizeof(float) ); // tableau des elts
        float *h_res = (float*) malloc( N*sizeof(float) ); // variable  resultat
     
     
        // remplissage des du tableau
        i = 0;
        while(i < N)
        {
            h_v1[i] = i;
            h_res[i]=0;
     
            i++;	
        }
     
        // declaration des elts sur le Gpu
        float *d_v1;
        float *d_res;
     
        cudaMalloc( (void**) &d_v1, N*sizeof(float) );	
        cudaMalloc( (void**) &d_res, N*sizeof(float) );	
     
        cudaMemcpy(d_v1, h_v1, N*sizeof(float), cudaMemcpyHostToDevice);
     
        /* ici je choisis 256 threds par bloc
        39063 = 10000000 / 256  ===> nombres de blocs */
     
        MoyenneTab<<<39063, 256>>>(d_v1, d_res);
     
        cudaThreadSynchronize();
     
        cudaMemcpy(h_res, d_res, N*sizeof(float), cudaMemcpyDeviceToHost);
     
        cudaFree(d_v1);
        cudaFree(d_res);
    }

  8. #8
    Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bonjour,
    j'ai trouvé une solution à mon problème du moins presque, car mon code me renvoit une erreur que je n'arrive pas à corriger.
    Ça serrait sympa si quelqu’un pourrait me dire ou' se trouve l'erreur.

    Le code calcul la moyenne des éléments se trouvant dans un Threads a[] et l enregistre dans un Tableau 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
    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
     
     
     
    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"
     
    #include <stdio.h>
     
    #define NUMOFTRACES (5000)
    #define NUMOFDATAPOINTS (256*6*14) 
    #define arraySize (NUMOFTRACES*NUMOFDATAPOINTS)
    #define Anzahl_block (256)
     
    cudaError_t addWithCuda(float *c, const float *a, unsigned int numtraces, unsigned int numdatapoints);
     
     
    __global__ void Mittelwert(float *c, const float *a, unsigned int numtraces, unsigned int numdatapoints)
    {
        float Sum=0;
     
        int mydatapoint=blockDim.x * blockIdx.x + threadIdx.x;
     
        for(int i=0; i<numtraces; i++)
        {
        Sum+=a[(size_t) i*numdatapoints + mydatapoint];
        }
     
        Sum/= numtraces;
        c[mydatapoint]= Sum;
     
    }
     
     
     main()
    {
     
     
        float *a = (float*) malloc( arraySize*sizeof(float) ); 
        float *c = (float*) malloc( NUMOFDATAPOINTS*sizeof(float) );
     
     
        //Initialisation de a[]
        for (int i=0;i<NUMOFTRACES;i++)
        {
            for (int j=0;j<NUMOFDATAPOINTS;j++)
            a[i*NUMOFDATAPOINTS+j] = j-3+(i%7); 
        } 
     
     
           // Add vectors in parallel.
            cudaError_t cudaStatus = addWithCuda(c, a, arraySize);
     
     
     
        // Affichage du resulta c[]
        for (int j=0;j<NUMOFDATAPOINTS;j++)
        {
                printf("c[%d] ===========> [%f]\n",j, c[j]);
        }
     
     
    }
     
    // Helper function for using CUDA to add vectors in parallel.
    cudaError_t addWithCuda(float *c, const float *a, unsigned int numtraces, unsigned int numdatapoints)
    {
        float *dev_a = 0;
        float *dev_c = 0;
        cudaError_t cudaStatus;
     
     
        // Allocate GPU buffers for two vectors (one input, one output)    .
        cudaMalloc((void**)&dev_c, numdatapoints * sizeof(float));
     
     
        cudaMalloc((void**)&dev_a, (size_t) numtraces *numdatapoints* sizeof(float));
     
     
        // Copy input vectors from host memory to GPU buffers.
        cudaMemcpy(dev_a, a, (size_t) numtraces*numdatapoints * sizeof(float), cudaMemcpyHostToDevice);
     
     
     
        // Launch a kernel on the GPU with one thread for each element.
        Mittelwert<<<numdatapoints/Anzahl_block, 256>>>(dev_c, dev_a);   
     
     
        // cudaDeviceSynchronize waits for the kernel to finish, and returns
        // any errors encountered during the launch.
         cudaDeviceSynchronize();
     
     
        // Copy output vector from GPU buffer to host memory.
        cudaMemcpy(c, dev_c, numdatapoints * sizeof(float), cudaMemcpyDeviceToHost);
     
     
    Error:
        cudaFree(dev_c);
        cudaFree(dev_a);
     
     
        return cudaStatus;
    }
    Merci bien pour votre aide.

    Army

  9. #9
    Candidat au Club
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Points : 2
    Points
    2
    Par défaut SOLUTION
    Pour ceux qui seront intéressés, j ai enfin trouve la solution à mon problème
    une fois de plus il s'agissait de calculer la moyenne ainsi que la variance d'un tableau
    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
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
     
    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"
    #include <time.h>
    #include <stdio.h>
    #include <omp.h>
     
     
    #define NUMOFTRACES (70000)
    #define NUMOFDATAPOINTS (256*6*14)  
    #define arraySize ((long long)NUMOFTRACES*NUMOFDATAPOINTS)
    #define Anzahl_block (256)
     
     
     
    // GPU BERECHNUNGSFUNKTION
    __global__ void Berechnung_Mittelwert_Varianz(float *Mittelwert, float *Varianz, const float *Vektor, unsigned int numtraces, unsigned int numdatapoints)
    {
        float Sum_varianz=0;
     
        float Sum_mittelwert=0;
     
        int mydatapoint=blockDim.x * blockIdx.x + threadIdx.x;
     
     
              for(int i=0; i<numtraces; i++)
                        {
                      float temp =Vektor[(size_t) i*numdatapoints + mydatapoint];
     
    				  //Bestimme den Mittelwert der Datenpunkte an der Stelle [i]
                        Sum_mittelwert += temp;  
                      //Bestimme den Mittelwert der QUADRATE der Datenpunkte an der Stelle [i]
                       Sum_varianz += temp*temp;
                           }
     
    		  Sum_mittelwert /= numtraces;
    		  Sum_varianz /= numtraces;
     
              Varianz[mydatapoint]= Sum_varianz-Sum_mittelwert*Sum_mittelwert ;
    		  Mittelwert[mydatapoint]=Sum_mittelwert;
     
    }
     
     
    // CPU BERECHNUNGSFUNKTION
    void Berechnung_Mittelwert_Varianz1(float *Mittelwert, float *Varianz, const float *Vektor, unsigned int numtraces, unsigned int numdatapoints)
    {
     
    #pragma omp parallel for
    	for(int j=0;j<NUMOFDATAPOINTS;j++)
    	{
     
    	float Sum_varianz=0;
        float Sum_mittelwert=0;
     
              for(int i=0; i<numtraces; i++)
                        {
     
                      float temp =Vektor[i*numdatapoints+j];
     
    				  //Bestimme den Mittelwert der Datenpunkte an der Stelle [i]
                        Sum_mittelwert += temp;  
                      //Bestimme den Mittelwert der QUADRATE der Datenpunkte an der Stelle [i]
                       Sum_varianz += temp*temp;
     
     
                           }
     
    		  Sum_mittelwert /= numtraces;
    		  Sum_varianz /= numtraces;
     
              Varianz[j]= Sum_varianz-Sum_mittelwert*Sum_mittelwert ;
    		  Mittelwert[j]=Sum_mittelwert;
     
    	}   
    }   
     
     
     
     
    int main()
    {
    	unsigned int numtraces = NUMOFTRACES ;
    	unsigned int numdatapoints = NUMOFDATAPOINTS;
     
    	// Zeit parameter
    	double start, end, start1, end1;	
     
    	//CPU (host)
        float *Vektor = (float*) malloc( arraySize*sizeof(float) ); 
    	float *Varianz = (float*) malloc( NUMOFDATAPOINTS*sizeof(float) );
        float *Mittelwert = (float*) malloc( NUMOFDATAPOINTS*sizeof(float) );   
     
        //Initialization von Vektor
        for (int i=0;i<NUMOFTRACES;i++)
                    {
            for (int j=0;j<NUMOFDATAPOINTS;j++)
            Vektor[i*NUMOFDATAPOINTS+j] = j-3+(i%7); 
                    }
     
        //GPU   	
        float *dev_Vektor = 0;
    	float *dev_Varianz = 0;
        float *dev_Mittelwert = 0;
     
        // Allocate GPU buffers for two vectors (one input, one output)    .
        cudaMalloc((void**)&dev_Mittelwert, numdatapoints * sizeof(float));
    	cudaMalloc((void**)&dev_Varianz, numdatapoints * sizeof(float)); 
        cudaMalloc((void**)&dev_Vektor, (size_t) numtraces *numdatapoints* sizeof(float));
     
        // START Die Zeit messen für die GPU
    	start = clock(); 
        cudaMemcpy(dev_Vektor, Vektor, (size_t) numtraces*numdatapoints * sizeof(float), cudaMemcpyHostToDevice);      
     
        // Launch a kernel on the GPU with one thread for each element.
        Berechnung_Mittelwert_Varianz<<<numdatapoints/Anzahl_block, 256>>>(dev_Mittelwert, dev_Varianz, dev_Vektor, numtraces, numdatapoints);   	   
     
        // Copy output vector from GPU buffer to host memory.
        cudaMemcpy(Mittelwert, dev_Mittelwert, numdatapoints * sizeof(float), cudaMemcpyDeviceToHost);
    	cudaMemcpy(Varianz, dev_Varianz, numdatapoints * sizeof(float), cudaMemcpyDeviceToHost);
     
    	 // cudaDeviceSynchronize waits for the kernel to finish, and returns
        // any errors encountered during the launch.
         cudaDeviceSynchronize(); 
    	// END Die Zeit messen für die GPU
    	end = clock(); 
    	// Ausgabe des Mittelwert und des Varianz
        for (int j=0;j<15;j++)
        {
                printf("Mittelwert[%d] == [%f] ===> Varianz[%d] == [%f]\n",j, Mittelwert[j],j, Varianz[j]);
     
        }
    	// START Die Zeit messen für die CPU
    	start1 = clock(); 
    	//CPU BERECHNUNGSFUNKTION
    	Berechnung_Mittelwert_Varianz1(Mittelwert, Varianz, Vektor, numtraces, numdatapoints);
    	// END Die Zeit messen für die CPU
    	end1 = clock();         
     
        // Ausgabe des Mittelwert und des Varianz
        for (int j=0;j<15;j++)
        {
                printf("Mittelwert[%d] == [%f] ===> Varianz[%d] == [%f]\n",j, Mittelwert[j],j, Varianz[j]);
     
        }
     
    	fprintf(stderr, "Time GPU in Sekunde : %f\n", (double)(end-start) / (double) CLOCKS_PER_SEC);
    	fprintf(stderr, "Time CPU in Sekunde : %f\n", (double)(end1-start1) / (double) CLOCKS_PER_SEC);
     
    	cudaFree(dev_Mittelwert);
    	cudaFree(dev_Varianz);
        cudaFree(dev_Vektor);	
     
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 26/10/2010, 22h14
  2. Calcul de la moyenne pour un tableau
    Par imados_xp dans le forum LabVIEW
    Réponses: 3
    Dernier message: 06/04/2009, 19h20
  3. Calcul de la moyenne d'un tableau 1D
    Par Marc29 dans le forum LabVIEW
    Réponses: 5
    Dernier message: 28/05/2008, 11h17
  4. [Tableaux] Calcul d'une moyenne à partir d'un tableau
    Par Mordanus dans le forum Langage
    Réponses: 13
    Dernier message: 09/05/2007, 18h03
  5. Problème dans le calcul des normales moyennes,
    Par MaxPayne dans le forum OpenGL
    Réponses: 1
    Dernier message: 12/04/2005, 17h50

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