NVPROF报告的交易指标究竟是什么?

时间:2016-04-20 22:55:04

标签: memory cuda gpu profiler nvprof

我试图找出" nvprof"所报告的每个指标究竟是什么?是。更具体地说,我无法确定哪些事务是系统内存和设备内存的读写。我写了一个非常基本的代码,只是为了帮助解决这个问题。

#define TYPE float
#define BDIMX 16
#define BDIMY 16
#include <cuda.h>
#include <cstdio>
#include <iostream>
__global__ void kernel(TYPE *g_output, TYPE *g_input, const int dimx, const int dimy)
{
__shared__ float s_data[BDIMY][BDIMX];
  int ix = blockIdx.x * blockDim.x + threadIdx.x;
  int iy = blockIdx.y * blockDim.y + threadIdx.y;
  int in_idx = iy * dimx + ix; // index for reading input
  int tx = threadIdx.x; // thread’s x-index into corresponding shared memory tile  
  int ty = threadIdx.y; // thread’s y-index into corresponding shared memory tile 
  s_data[ty][tx] = g_input[in_idx];
  __syncthreads();
  g_output[in_idx] = s_data[ty][tx] * 1.3;
  }


int main(){
  int size_x = 16, size_y = 16;
  dim3 numTB;
    numTB.x = (int)ceil((double)(size_x)/(double)BDIMX) ;
    numTB.y = (int)ceil((double)(size_y)/(double)BDIMY) ;
  dim3 tbSize; 
  tbSize.x = BDIMX;
  tbSize.y = BDIMY;
  float* a,* a_out;
  float *a_d = (float *) malloc(size_x * size_y * sizeof(TYPE));
  cudaMalloc((void**)&a,     size_x * size_y * sizeof(TYPE));
  cudaMalloc((void**)&a_out, size_x * size_y * sizeof(TYPE));
  for(int index = 0; index < size_x * size_y; index++){
      a_d[index] = index;
   }
  cudaMemcpy(a, a_d, size_x * size_y * sizeof(TYPE), cudaMemcpyHostToDevice);
  kernel <<<numTB, tbSize>>>(a_out, a, size_x, size_y);
  cudaDeviceSynchronize();
  return 0;
}

然后我运行nvprof --metrics all输出以查看所有指标。这是我感兴趣的部分:

           Metric Name                        Metric Description         Min         Max         Avg
Device "Tesla K40c (0)"
  Kernel: kernel(float*, float*, int, int)
    local_load_transactions                   Local Load Transactions           0           0           0
   local_store_transactions                  Local Store Transactions           0           0           0
   shared_load_transactions                  Shared Load Transactions           8           8           8
  shared_store_transactions                 Shared Store Transactions           8           8           8
           gld_transactions                  Global Load Transactions           8           8           8
           gst_transactions                 Global Store Transactions           8           8           8
   sysmem_read_transactions           System Memory Read Transactions           0           0           0
  sysmem_write_transactions          System Memory Write Transactions           4           4           4
     tex_cache_transactions                Texture Cache Transactions           0           0           0
     dram_read_transactions           Device Memory Read Transactions           0           0           0
    dram_write_transactions          Device Memory Write Transactions          40          40          40
       l2_read_transactions                      L2 Read Transactions          70          70          70
      l2_write_transactions                     L2 Write Transactions          46          46          46

我理解共享和全局访问。全局访问是合并的,因为有8个warp,所以有8个事务。 但我无法弄清楚系统内存和设备内存写入事务编号。

1 个答案:

答案 0 :(得分:3)

如果您拥有一个具有逻辑物理空间的GPU内存层次结构模型,例如here,则会有所帮助。

参考“概览标签”图表:

  1. gld_transactions是指从针对全局逻辑空间的warp发出的事务。在图中,这将是从左侧的“内核”框到右侧的“全局”框的行,逻辑数据移动方向将从右到左。

  2. gst_transactions指的是与上面相同的行,但逻辑上是从左到右。请注意,这些逻辑全局事务可能会在缓存中命中,之后不会到达任何地方。从指标的角度来看,这些交易类型仅涉及图中指示的行。

  3. dram_write_transactions是指图中连接右侧设备内存和L2缓存的行,逻辑数据流在此行上从左到右。由于L2高速缓存行是32字节(而L1高速缓存行和全局事务的大小是128字节),因此设备存储器事务也是32字节,而不是128字节。因此,通过L1(如果启用它是直写高速缓存)和L2的全局写事务将生成4个dram_write事务。这应解释40项交易中的32项。

  4. 系统内存事务以零拷贝主机内存为目标。你似乎没有这个,所以我无法解释这些。

  5. 请注意,在某些情况下,对于某些指标,在某些GPU上,启动非常少量的线程块时,探查器可能会有一些“不准确”。例如,某些指标是基于每个SM进行采样并进行缩放。 (但是,设备内存事务不在此类别中)。如果您在每个SM上完成了不同的工作(可能是由于启动了非常少量的线程块),那么缩放可能会误导/不准确。通常,如果您启动大量的线程块,这些通常会变得微不足道。