Cuda 当分配的内存增加时,多GPU性能会下降 我在Windows 7 x64,Visual C++ 10:上测试了一个带有4GB RAM的GTX 690 GPU。

Cuda 当分配的内存增加时,多GPU性能会下降 我在Windows 7 x64,Visual C++ 10:上测试了一个带有4GB RAM的GTX 690 GPU。,cuda,multi-gpu,Cuda,Multi Gpu,我已经编写了一个函数,它接收2个向量并将其添加到第3个向量中。该任务在2个GPU设备上中断。我逐渐增加了向量大小,以测试GPU性能。所需时间相对于向量大小线性增加到某一点,然后突然增加。当我禁用每个GPU内核时,所需的时间与可用内存的结束保持线性关系。我附上了一张图表,显示了所需的时间和分配的内存 您可以在此处看到速度图: 你能告诉我怎么了吗 最好的, 拉明 这是我的代码: unsigned BenchMark( unsigned VectorSize ) { unsigned *

我已经编写了一个函数,它接收2个向量并将其添加到第3个向量中。该任务在2个GPU设备上中断。我逐渐增加了向量大小,以测试GPU性能。所需时间相对于向量大小线性增加到某一点,然后突然增加。当我禁用每个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 ] ; 
}
无符号基准测试(无符号向量大小)
{
未签名*D[2][3];
对于(int i=0;i<2;i++)
{
cudaSetDevice(i);
对于(int j=0;j<3;j++)
Cudamaloc(&D[i][j],向量大小*大小(无符号));
}
无符号uStartTime=时钟();
//试验
对于(int i=0;i<2;i++)
{
cudaSetDevice(i);
添加内核(
D[i][0],,
D[i][1],
D[i][2],,
矢量大小);
}
cudaDeviceSynchronize();
cudaSetDevice(0);
cudaDeviceSynchronize();
无符号uEndTime=时钟();
对于(int i=0;i<2;i++)
{
cudaSetDevice(i);
对于(int j=0;j<3;j++)
cudaFree(D[i][j]);
}
返回uEndTime-uStartTime;
}
__全局无效添加内核(
常量Npp32u*\uuuuu限制\uuuuuu pSource1,
常量Npp32u*\uuuuu限制\uuuuuo资源2,
Npp32u*\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,
未签名(长度)
{
无符号x=blockIdx.x*blockDim.x+threadIdx.x;
if(x
我找到了答案。问题发生在SLI处于活动状态时,我禁用了它,现在它工作正常。

可视化探查器可能会给您一些线索。您是否检查过其中一个CUDA API调用中是否发生错误?也许cudaSetDevice调用失败。然后,内核将在错误的设备上调用,使用诸如UVA和对等访问等功能读取和写入其他设备内存,从而对性能产生极端影响。亲爱的Kronos,我检查了错误,这确实是在不同的内核上完成的。在大向量上,所需的内存量不能分配到一个内核上。亲爱的Robert,我使用了Visual Profiler,当使用较小的向量时,两个AddKernel之间的运行延迟非常小,但当向量大小增加时,此延迟非常大,一个内核在另一个内核启动任务将近1秒后启动任务,探查器显示在此期间处于空闲状态。