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.
Utilisez-vous la carte GPU pour afficher la vidéo et exécuter les noyaux CUDA? –
Oui, et il se pourrait bien que ce soit GPU1. Mais doubler le temps pour une copie de la mémoire? – zenna
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