CUDA:示例代码具有300%多GPU缩放/性能优化

时间:2014-04-01 17:32:55

标签: performance optimization cuda

我正在尝试使用CUDA将NBody问题解决代码移植到GPU。

Nvidia在CUDA SDK附带的样本中提供了一个NBody解决模拟。它在samples / 5_Simulations / nbody中。

我不是C ++或CUDA的专家,很难理解他们的代码分布在几个文件中,所以我最终决定编写我自己的http://docs.nvidia.com/cuda/samples/5_Simulations/nbody/doc/nbody_gems3_ch31.pdf中描述的算法实现。

我的实施很快就成功了,我能够在GTX Titan上每秒计算250亿次双精度交互。当我使用-benchmark -fp64运行它们的实现时,我获得了相同的性能。这对我来说是令人惊讶的,因为在我上面链接的文章中,它们在200Gflop(单精度)卡上每秒达到100亿次单精度交互。 GTX titan大约是1.3 Tflops(双精度)因此我预计双精度每秒650亿次交互。

当我用-benchmark -fp64 -numdevices = 6运行它们的实现时,为了增加神秘感,计算速度提高了18倍。这相当于300%缩放???通过将-numbodies设置为比其默认值大十倍,为GPU添加更多工作会产生450%缩放???

我应该补充一点,我正在运行CUDA SDK 5.5版本的nbody实现,并且该系统基于6个相同的GTX巨头。

我已经尝试了很多东西来在我的单个GPU代码上获得超过250亿次交互,但是根据nvvp,内存访问效率接近100%并且占用率为50%(所有增加的尝试次数),它似乎真的达到了顶峰它没有为表现做任何事情。)

是否有任何可以让GPU具有300%缩放率的机制?

我的代码是否真的像我预期的那样,通过翻牌来判断它的运行速度提高2-3倍?

cuda提供的样本是否有问题?

以防万一这是内核的简单版本:

__global__
void Force_GPU(double4 *d_r,double3 *d_F){
    unsigned int idx=threadIdx.x;
    unsigned int index=blockIdx.x*blockDim.x+idx;
    __shared__ double4 sharedpos[tilesize];
    double4 position=d_r[index];
    double3 temp_r,force={0.0,0.0,0.0};
    double temp_d;
    #pragma unroll
    for(int tile=0;tile<numtiles;tile++){
        sharedpos[idx]=d_r[tile*tilesize+idx];
        __syncthreads();
        #pragma unroll
        for(int j=0;j<tilesize;j++){
            temp_r.x = position.x -sharedpos[j].x;
            temp_r.y = position.y -sharedpos[j].y;
            temp_r.z = position.z -sharedpos[j].z;
            temp_d = temp_r.x * temp_r.x + temp_r.y * temp_r.y + temp_r.z * temp_r.z+1e-23;
            temp_d = rsqrt(temp_d);
            temp_d *= temp_d*temp_d;
            temp_d *=sharedpos[j].w;
            force.x += temp_r.x * temp_d;
            force.y += temp_r.y * temp_d;
            force.z += temp_r.z * temp_d;
        }
        __syncthreads();
    }
    d_F[index]=force;
}

我有更多令人困惑的优化内存流并摆脱软化参数1e-23,但性能影响对于内存优化(我认为不是很多数据)和小(但很清楚)都不存在软化参数(需要更复杂的控制流程以避免计算粒子本身的力)。正如我所说,我也尝试增加占用率,但它受到每个SM 2048个中1024个线程的寄存器的限制。强制降低寄存器使用率会产生可怜的性能,还需要弄乱磁贴以减少共享内存的使用。

非常感谢任何帮助和意见。

1 个答案:

答案 0 :(得分:2)

  

cuda提供的样本是否有问题?

我相信通过CUDA 5.5的nbody示例代码中存在/是一个错误,它在多GPU设置中开始生效4 GPU或更多(甚至可能有2个GPU或更多)。您可以通过使用cuda-memcheck运行nbody示例代码来获得一些指示。

它可以在目前可用的CUDA 6 RC跌落中修复,我还没有检查过。