2016-12-07 2 views
-2

Je travaille donc sur une affectation qui implique le codage en C en utilisant CUDA. J'ai écrit une fonction et un noyau qui fonctionnent (produire le résultat correct). Cependant, je cherche à augmenter la vitesse.Copie CUDA et appel de noyau dans une boucle

Ceci est le noyau:

__global__ void update_c(const double *d_u, double *d_u_new, const int nx, const double k) 
{ 
    int i = blockDim.x * blockIdx.x + threadIdx.x; 

    if (i < nx-1 && i > 0) 
    { 
     d_u_new[i] = d_u[i] + k*(d_u[i+1] + d_u[i-1] -2*d_u[i]); 
    } 
} 

et c'est la fonction:

void update() { 

    cudaMemcpy(d_u, u, size, cudaMemcpyHostToDevice); 
    cudaMemcpy(d_u_new, u_new, size, cudaMemcpyHostToDevice); 
    update_c<<<blocksPerGrid, threadsPerBlock>>>(d_u, d_u_new, nx, k); 
    cudaMemcpy(u, d_u, size, cudaMemcpyDeviceToHost); 
    cudaMemcpy(u_new, d_u_new, size, cudaMemcpyDeviceToHost); 

    double *tmp = u_new; u_new = u; u = tmp; 
} 

Je comprends qu'une fois copié d_u et d_u_new resteront sur l'appareil, donc je ne pas besoin de les copier chaque fois. Ma question est comment puis-je réécrire cela pour utiliser les variables encore et encore et seulement copier la mémoire au début et à la fin du programme? Je suis tout nouveau à CUDA et n'ai eu qu'un très bref cours intensif avant que cela ne soit assigné.

+0

Nous devons voir le code qui appelle 'update()' pour le savoir. Pourriez-vous ajouter plus de contexte? –

Répondre

0

j'ai pu le réparer en créant les éléments suivants:

__global__ void update_c(const double *d_u, double *d_u_new, const int nx, const double k) 
{ 
    int i = blockDim.x * blockIdx.x + threadIdx.x; 

    if (i < nx-1 && i > 0) 
    { 
     d_u_new[i] = d_u[i] + k*(d_u[i+1] + d_u[i-1] -2*d_u[i]); 
    } 
} 

void copyToDev(){ 
    cudaMemcpy(d_u, u, size, cudaMemcpyHostToDevice); 
    cudaMemcpy(d_u_new, u_new, size, cudaMemcpyHostToDevice); 
} 

void copyToHost(){ 
    cudaMemcpy(u, d_u, size, cudaMemcpyDeviceToHost); 
    cudaMemcpy(u_new, d_u_new, size, cudaMemcpyDeviceToHost); 
} 

/* updates u for next time step. */ 
void update() { 

    update_c<<<blocksPerGrid, threadsPerBlock>>>(d_u, d_u_new, nx, k); 
    double *tmp = d_u_new; d_u_new = d_u; d_u = tmp; 
} 

J'appelle copyToDev() avant que la boucle qui appelle la mise à jour et copyToHost après.