cuda - 无法达到最佳性能

标签 cuda benchmarking

我试图通过下面的代码达到每个SM的最佳性能。峰值位于 25 GFlops(GTX275-GT200 Arch.)之间。此代码最多提供 8 GFlops。

__global__ void new_ker(float *x)
{
  int index = threadIdx.x+blockIdx.x*blockDim.x;
  float a,b;
  a=0;
  b=x[index];
  //LOOP=10000000
  //No. of blocks = 1
  //Threads per block = 512 (I'm using GTX 275 - GT200 Arch.)
  #pragma unroll 2048
  for(int i=0;i<LOOP;i++){
       a=a*b+b;
  }  

  x[index] = a;

 }

我不想在代码中增加 ILP。有什么想法为什么它没有达到顶峰吗?

int main(int argc,char **argv)
{

   //Initializations
   float *x;
   float *dx;
   cudaEvent_t new_start,new_stop;
   float elapsed;
   double gflops;
   x = 0;
   flag = 0;
   cudaMalloc((void **)&dx,sizeof(float)*THPB);

   //ILP=1  
   cudaEventCreate(&new_start);
   cudaEventCreate(&new_stop);
   printf("Kernel1:\n");
   cudaEventRecord(new_start, 0);
   new_ker<<<BLOCKS,THPB>>>(dx);
   cudaEventRecord(new_stop,0);
   cudaEventSynchronize(new_stop);
   cudaEventElapsedTime(&elapsed,new_start,new_stop);
   x = (float *)malloc(sizeof(float)*THPB);
   cudaMemcpy(x,dx,sizeof(float)*THPB,cudaMemcpyDeviceToHost);

   gflops = ((double)(BLOCKS)*(THPB)*LOOP/elapsed)/1000000;
   printf("\t%f",gflops);
   cudaEventDestroy(new_start);
   cudaEventDestroy(new_stop);
   return 0;
}

平台: CUDA 3.0 NVIDIA GeForce GTX275 (GT200)

最佳答案

如果我使用正确的 FLOP 计算将您的代码中的完整重现案例放在一起:

#include <stdio.h> 

#define LOOP (10000000)
#define BLOCKS (30)
#define THPB (512)

__global__ void new_ker(float *x)
{
  int index = threadIdx.x+blockIdx.x*blockDim.x;
  float a,b;
  a=0;
  b=x[index];
  #pragma unroll 2048
  for(int i=0;i<LOOP;i++){
       a=a*b+b;
  }  

  x[index] = a;
}

int main(int argc,char **argv)
{

   //Initializations
   float *x;
   float *dx;
   cudaEvent_t new_start,new_stop;
   float elapsed;
   double gflops;
   x = 0;
   cudaMalloc((void **)&dx,sizeof(float)*THPB);

   //ILP=1  
   cudaEventCreate(&new_start);
   cudaEventCreate(&new_stop);
   printf("Kernel1:\n");
   cudaEventRecord(new_start, 0);
   new_ker<<<BLOCKS,THPB>>>(dx);
   cudaEventRecord(new_stop,0);
   cudaEventSynchronize(new_stop);
   cudaEventElapsedTime(&elapsed,new_start,new_stop);
   x = (float *)malloc(sizeof(float)*THPB*BLOCKS);
   cudaMemcpy(x,dx,sizeof(float)*THPB*BLOCKS,cudaMemcpyDeviceToHost);

   gflops = 2.0e-6 * ((double)(LOOP)*double(THPB*BLOCKS)/(double)elapsed);
   printf("\t%f\n",gflops);
   cudaEventDestroy(new_start);
   cudaEventDestroy(new_stop);
   return 0;
}

我编译它并在 64 位 Linux 平台上使用 CUDA 3.2 的 1.4GHz GTX275 上运行它:

$ nvcc -arch=sm_13 -Xptxas="-v" -o perf perf.cu
ptxas info    : Compiling entry function '_Z7new_kerPf' for 'sm_13'
ptxas info    : Used 4 registers, 8+16 bytes smem, 8 bytes cmem[1]
$ ./perf 
Kernel1:
        671.806039

对于运行纯 FMAD 代码的卡,我得到的峰值 FLOP/s 的误差在 0.01% 以内(1.4 GHz * 2 FLOP * 8 核/MP * 30 MP)= 672 GFLOP/s。

看来代码实际上确实达到了每个多处理器一个 block 的峰值 FLOP/s,但您只是没有正确计算 FLOP/s 数。

关于cuda - 无法达到最佳性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8709552/

相关文章:

cuda - 计算条件均值

cuda - 什么时候纹理内存应该优先于常量内存?

linux - 在c++ 11 std::thread中执行的时间开销是否取决于所执行的有效负载?

python - 基准测试 - posix-aio 与 libaio

c# - 为什么 IDE 不提供像断点这样的内置代码计时功能?

opencv - 具有GPU支持的OpenCV编译,但仍从gpu::getCudaEnabledDeviceCount();获得0。

c++ - 使用CUDA convnet库编译错误

cuda - 高版本 CUDA 对于计算能力较低的设备的好处

java - 如何使用 Java 12 的 Microbenchmark Suite?

c++ - Trying Favorite Tries : Radix, 后缀,和哈希!甚至三元组,天哪!