Производительность нескольких графических процессоров снижается при увеличении выделенной памяти

Я протестировал следующее на графическом процессоре GTX 690 с 4 ГБ ОЗУ в Windows 7 x64, Visual C++ 10:

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

Вы можете увидеть диаграмму скорости здесь: Диаграмма сравнения скоростей!

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

Бестс, Рамин

Это мой код:

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 ] ; 
}

person Ramin Halavati    schedule 13.06.2013    source источник
comment
Визуальный профилировщик может дать вам некоторые подсказки.   -  person Robert Crovella    schedule 13.06.2013
comment
Вы проверили, произошла ли ошибка в одном из вызовов API CUDA? Возможно, вызов cudaSetDevice не работает. Затем ядро ​​будет вызываться не на том устройстве с использованием таких функций, как UVA и одноранговый доступ для чтения и записи памяти других устройств, что приведет к сильному снижению производительности.   -  person Michael Haidl    schedule 13.06.2013
comment
Уважаемый Kronos, я проверил ошибки и это действительно делается на разных ядрах. На больших векторах необходимое количество памяти не может быть выделено на одном ядре.   -  person Ramin Halavati    schedule 13.06.2013
comment
Уважаемый Роберт, я использовал Visual Profiler, когда используются меньшие векторы, два ядра AddKernel запускаются с очень маленькой задержкой между ними, но когда размеры векторов увеличиваются, эта задержка очень велика, и одно ядро ​​​​запускает задачу почти через 1 секунду после другого. и профилировщик показывает, что он простаивает в это время.   -  person Ramin Halavati    schedule 15.06.2013


Ответы (1)


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

person Ramin Halavati    schedule 15.06.2013