2010-04-01 7 views
0

Ma société a une configuration de deux GTX 295, donc un total de 4 GPU dans un serveur, et nous avons plusieurs serveurs. Nous GPU 1 spécifiquement était lent, en comparaison avec GPU 0, 2 et 3, donc j'ai écrit un petit test de vitesse pour aider à trouver la cause du problème.CUDA: La copie de mémoire vers GPU 1 est plus lente dans multi-GPU

//#include <stdio.h> 
//#include <stdlib.h> 
//#include <cuda_runtime.h> 
#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
#include <cutil.h> 

__global__ void test_kernel(float *d_data) { 
    int tid = blockDim.x*blockIdx.x + threadIdx.x; 
    for (int i=0;i<10000;++i) { 
     d_data[tid] = float(i*2.2); 
     d_data[tid] += 3.3; 
    } 
} 

int main(int argc, char* argv[]) 
{ 

    int deviceCount;               
    cudaGetDeviceCount(&deviceCount); 
    int device = 0; //SELECT GPU HERE 
    cudaSetDevice(device); 


    cudaEvent_t start, stop; 
    unsigned int num_vals = 200000000; 
    float *h_data = new float[num_vals]; 
    for (int i=0;i<num_vals;++i) { 
     h_data[i] = float(i); 
    } 

    float *d_data = NULL; 
    float malloc_timer; 
    cudaEventCreate(&start); 
    cudaEventCreate(&stop); cudaEventRecord(start, 0); 
    cudaMemcpy(d_data, h_data, sizeof(float)*num_vals,cudaMemcpyHostToDevice); 
    cudaMalloc((void**)&d_data, sizeof(float)*num_vals); 
    cudaEventRecord(stop, 0); cudaEventSynchronize(stop); cudaEventElapsedTime(&malloc_timer, start, stop); 
    cudaEventDestroy(start); 
    cudaEventDestroy(stop); 


    float mem_timer; 
    cudaEventCreate(&start); 
    cudaEventCreate(&stop); cudaEventRecord(start, 0); 
    cudaMemcpy(d_data, h_data, sizeof(float)*num_vals,cudaMemcpyHostToDevice); 
    cudaEventRecord(stop, 0); cudaEventSynchronize(stop); cudaEventElapsedTime(&mem_timer, start, stop); 
    cudaEventDestroy(start); 
    cudaEventDestroy(stop); 

    float kernel_timer; 
    cudaEventCreate(&start); 
    cudaEventCreate(&stop); cudaEventRecord(start, 0); 
    test_kernel<<<1000,256>>>(d_data); 
    cudaEventRecord(stop, 0); cudaEventSynchronize(stop); cudaEventElapsedTime(&kernel_timer, start, stop); 
    cudaEventDestroy(start); 
    cudaEventDestroy(stop); 

    printf("cudaMalloc took %f ms\n",malloc_timer); 
    printf("Copy to the GPU took %f ms\n",mem_timer); 
    printf("Test Kernel took %f ms\n",kernel_timer); 

    cudaMemcpy(h_data,d_data, sizeof(float)*num_vals,cudaMemcpyDeviceToHost); 

    delete[] h_data; 
    return 0; 
} 

Les résultats sont

GPU0 cudaMalloc a pris 0.908640 ms copie au GPU a pris 296.058777 ms test du noyau ont 326.721283 ms

GPU1 cudaMalloc a pris 0.913568 ms copie au GPU a pris 663.182251 ms Le noyau de test a pris 326.710785 ms

GPU2 cudaMalloc a pris 0.925600 ms copie au GPU a pris 296.915039 ms test du noyau A pris 327.127930 ms

GPU3 cudaMalloc a pris 0.920416 ms copie au GPU a pris 296.968384 ms test du noyau ont 327.038696 ms

Comme vous pouvez le voir, le cudaMemcpy au GPU est deux fois plus long que GPU1. Ceci est cohérent entre tous nos serveurs, c'est toujours GPU1 qui est lent. Des idées pourquoi cela pourrait-il être? Tous les serveurs exécutent Windows XP.

+0

Utilisez-vous la carte GPU pour afficher la vidéo et exécuter les noyaux CUDA? –

+0

Oui, et il se pourrait bien que ce soit GPU1. Mais doubler le temps pour une copie de la mémoire? – zenna

+0

Lorsque j'utilise le même code sur une machine GPU, où le GPU est utilisé pour l'affichage et l'exécution de CUDA, il est toujours rapide autour de 300ms, donc l'affichage ne peut pas prendre en compte le temps d'exécution supplémentaire de 300ms – zenna

Répondre

1

Ce fut un problème de pilote. La mise à jour du dernier pilote l'a corrigé

0

Cela peut être un problème avec votre bus PCI, essayez d'échanger les cartes dans des emplacements différents pour voir si le problème persiste. Si c'est un problème, copiez toutes vos données sur le gtx295 via le slot le plus rapide et utilisez sli top copiez-le sur l'autre gpu (bus PCI lent).

0

Si vous pouvez utiliser le gddr de la carte vidéo plus rapide à charger, alors vous pouvez faire un transfert de périphérique à beaucoup plus de bande passante, ce qui pourrait aider à éliminer le problème aussi. Vérifiez également votre bande passante grâce au test de bande passante de NVidia pour obtenir des résultats physiques et des tests.

Bonne chance!

0

Exécutez-vous une configuration à double processeur? Il y a un bug dans les chipsets actuels de Tylersburg: la bande passante du chemin x86 (0) vers GPU (1) est plus lente que le chemin direct de x86 (0) vers GPU (0). Intel devrait sortir une nouvelle version pour corriger ce bug. Essayez de verrouiller votre processus de test à un processeur spécifique en utilisant taskset et voir quels résultats vous obtenez.

ce qui concerne Mark

Questions connexes