В моей компании настроено два GTX 295, так что в общей сложности 4 графических процессора на сервере, и у нас есть несколько серверов.
У нас GPU 1 был медленным, по сравнению с GPU 0, 2 и 3, поэтому я написал небольшой тест скорости, чтобы найти причину проблемы.
//#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;
}
Результаты
GPU0
cudaMalloc заняло 0,908640 мс
Копирование в GPU заняло 296,058777 мс
Проверка ядра заняла 326,721283 мс
GPU1
cudaMalloc заняло 0,913568 мс
Копирование в GPU заняло 663.182251 мс
Проверка ядра заняла 326,710785 мс
GPU2
cudaMalloc заняло 0,925600 мс
Копирование в GPU заняло 296,915039 мс
Тест ядра занял 327.127930 мс
GPU3
cudaMalloc заняло 0,920416 мс
Копирование в GPU заняло 296,968384 мс
Проверка ядра заняла 327.038696 мс
Как видите, cudaMemcpy для GPU вдвое больше времени для GPU1. Это согласовано между всеми нашими серверами, это всегда GPU1, который работает медленно.
Есть идеи, почему это может быть?
Все серверы работают под управлением Windows XP.