CUDA 8.0,GTX 1080,为什么矢量加法比矩阵乘法慢5倍?

时间:2016-07-29 09:36:53

标签: cuda gpu

我正在使用最新的CUDA 8.0和GTX 1080,并运行样本来测试速度。 (我知道它们没有反映出最佳速度,但我只是想横向比较。)

0_Simple/matrixMul中,速度由代码测量,它给出:

Performance= 1029.91 GFlop/s, Time= 0.127 msec, Size= 131072000 Ops, WorkgroupSize= 1024 threads/block

然后我运行0_Simple/vectorAdd,并从上面的示例中复制速度测试代码。即:

// Measure speed
    cudaEvent_t start;
    cudaEventCreate(&start);
    cudaEvent_t stop;
    cudaEventCreate(&stop);

    cudaEventRecord(start, NULL);
    int nIter = 300;
    for (int i = 0; i < nIter; i++) {
        vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, numElements);
    }
    cudaEventRecord(stop, NULL);

    cudaEventSynchronize(stop);
    float msecTotal = 0.0f;
    cudaEventElapsedTime(&msecTotal, start, stop);
    float msecPerAdd = msecTotal / nIter;
    double flopsPerAdd = numElements;
    double gigaFlops = (flopsPerAdd * 1.0e-9f) / (msecPerAdd / 1000.0f);
    printf("Performance= %.2f GFLOPS, Time= %.3f ms, Size= %.0f Ops\n", gigaFlops, msecPerAdd, flopsPerAdd);

我还将numElements50000放大到67108864。速度结果是:

Performance= 19.85 GFLOPS, Time= 3.380 ms, Size= 67108864 Ops

慢了近5倍。

我知道示例代码可能不是最理想的,所以有人能告诉我为什么vectorAdd代码太慢了,以及如何优化它?

我正在使用CUDA 8.0和GTX 1080

2 个答案:

答案 0 :(得分:3)

与矩阵乘法不同,向量加法是一种内存带宽绑定操作。衡量其性能的正确方法是测量全局内存访问的带宽。对于向量加法,它包括2个输入和1个输出向量,并且可以如下计算。

3 * numElements * sizeof(d_A[0]) / kernel_running_time

您可以将其与简单D2D副本的带宽进行比较,看看您是否已达到峰值。

答案 1 :(得分:-1)

编辑:添加了GPU和CPU的代码

我运行以下实验

*** Cuda内核

__global__ void add(float *a, float *c , size_t N)
{
  int tid = blockIdx.x*blockDim.x + threadIdx.x;    
  if(tid < N) a[tid] += c[tid];
}

*** CPU天真版本(基线)

void naiveAdd(float *h_a, float *h_c, size_t N)
{
   for (size_t i=0; i<N; i++)
      h_a[i] += h_c[i];
}

用于在具有不同CUDA GCC版本的同一机器(740M GPU,第4代i7)中添加两个向量的性能比较。

在CUDA 8.0和GCC 5上,GPU版本较慢 enter image description here

在CUDA 7.5和GCC 4.8上,GPU版本更快 enter image description here

有了这个证据,我可以得出结论,目前最好避免使用CUDA 8.0。