2013-06-13 6 views
0

Я проверил следующее на GTX 690 GPU с 4 Гб оперативной памяти в Windows 7 x64, Visual C++ 10:нескольких ухудшать производительность GPU при выделенной памяти увеличивает

я написал функцию, которая получает 2 вектора и добавляет в третий вектор. Задача разбита на 2 устройства GPU. Я постепенно увеличил векторный размер до производительности графического процессора. Требуемое время линейно увеличивается относительно размера вектора до определенной точки, а затем резко скачет вверх. Когда я отключу каждый из ядер GPU, необходимое время остается линейным до конца доступной памяти. Я включил диаграмму, отображающую требуемое время и выделенную память.

Вы можете увидеть диаграмму скорости здесь: Speed Comparison Diagram!

Можете ли вы сказать мне, что случилось?

Bests, Рамин

Это мой код:

unsigned BenchMark(unsigned VectorSize) 
{ 
    unsigned *  D[ 2 ][ 3 ] ; 

    for (int i = 0 ; i < 2 ; i++) 
    { 
     cudaSetDevice(i) ; 

     for (int j = 0 ; j < 3 ; j++) 
      cudaMalloc(& D[ i ][ j ] , VectorSize * sizeof(unsigned)) ; 
    } 

    unsigned uStartTime = clock() ; 

    // TEST 
    for (int i = 0 ; i < 2 ; i++) 
    { 
     cudaSetDevice(i) ; 

     AddKernel<<<VectorSize/256,256>>>(
      D[ i ][ 0 ] , 
      D[ i ][ 1 ] , 
      D[ i ][ 2 ] , 
       VectorSize) ; 
    } 

    cudaDeviceSynchronize() ; 
    cudaSetDevice(0) ; 
    cudaDeviceSynchronize() ; 

    unsigned uEndTime = clock() ; 

    for (int i = 0 ; i < 2 ; i++) 
    { 
     cudaSetDevice(i) ; 

     for (int j = 0 ; j < 3 ; j++) 
      cudaFree(D[ i ][ j ]) ; 
    } 

    return uEndTime - uStartTime ; 
} 

__global__ void AddKernel(
        const Npp32u * __restrict__ pSource1 , 
        const Npp32u * __restrict__ pSource2 , 
         Npp32u * __restrict__ pDestination , 
         unsigned   uLength) 
{ 
    unsigned x = blockIdx.x * blockDim.x + threadIdx.x ; 

    if (x < uLength) 
     pDestination[ x ] = pSource1[ x ] + pSource2[ x ] ; 
} 
+0

Визуальный профайлер может дать вам некоторые подсказки. –

+0

Вы проверили, произошла ли ошибка в одном из вызовов API CUDA? Возможно, вызов cudaSetDevice завершился неудачно. Чем ядро ​​будет вызываться на неправильном устройстве, используя такие функции, как UVA и одноранговый доступ, чтобы читать и записывать память других устройств, что приводит к экстремальному влиянию производительности. –

+0

Дорогой Кронос, я проверил ошибки, и это действительно сделано на разных ядрах. На больших векторах требуемый объем памяти не может быть выделен на одном ядре. –

ответ

1

Я нашел ответ. Проблема произошла, поскольку SLI был активным, я отключил его, и теперь он работает плавно.