Performance OpenCL极低的GFLOPS,无数据传输瓶颈

Performance OpenCL极低的GFLOPS,无数据传输瓶颈,performance,opencl,gpgpu,Performance,Opencl,Gpgpu,我正在尝试优化我在我的GPU(AMD HD6850)上运行的算法。我计算了内核中浮点操作的数量,并测量了它的执行时间。我发现它可以达到约20 SP GFLOPS,但是根据GPU规格,我应该达到约1500 GFLOPS 为了找到瓶颈,我创建了一个非常简单的内核: kernel void test_gflops(const float d, global float* result) { int gid = get_global_id(0); float cd; for (

我正在尝试优化我在我的GPU(AMD HD6850)上运行的算法。我计算了内核中浮点操作的数量,并测量了它的执行时间。我发现它可以达到约20 SP GFLOPS,但是根据GPU规格,我应该达到约1500 GFLOPS

为了找到瓶颈,我创建了一个非常简单的内核:

kernel void test_gflops(const float d, global float* result)
{
    int gid = get_global_id(0);
    float cd;

    for (int i=0; i<100000; i++)
    {
        cd = d*i;
    }

    if (cd == -1.0f)
    {
        result[gid] = cd;
    }
}
内核无效测试\u gflops(常量浮点d,全局浮点*结果)
{
int gid=获取全局id(0);
浮动光盘;

对于(int i=0;i,这里有几个技巧:

  • GPU根本不喜欢循环。请使用#pragma unroll来展开循环
  • 你的GPU擅长向量运算。坚持它,这将允许你同时处理多个操作数
  • 无论是否可能,使用矢量加载/存储
  • 测量内存带宽——我几乎可以肯定,由于糟糕的访问模式,您的带宽是有限的
  • 在我看来,内核应该是这样的:

    typedef union floats{
        float16 vector;
        float array[16];
    } floats;
    
    kernel void test_gflops(const float d, global float* result)
    {
        int gid = get_global_id(0);
        floats cd;
        cd.vector = vload16(gid, result);
        cd.vector *= d;
    
        #pragma unroll
        for (int i=0; i<16; i++)
        {
            if(cd.array[i] == -1.0f){
            result[gid] = cd;
        }
    }
    
    typedef联合浮动{
    16载体;
    浮点数组[16];
    }浮动;
    内核无效测试(常量浮点d,全局浮点*结果)
    {
    int gid=获取全局id(0);
    浮动cd;
    cd.vector=vload16(gid,结果);
    cd.vector*=d;
    #布拉格展开
    
    对于(int i=0;iMy的第一印象是,
    i
    int
    float
    的转换在您的GPU上可能很昂贵?