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

Memory NVPROF报告的交易指标究竟是什么?,memory,cuda,gpu,profiler,nvprof,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 *

我试图弄清楚“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;
}
我了解共享和全局访问。全局访问是合并的,因为有8个扭曲,所以有8个事务。
但我无法计算出系统内存和设备内存写入事务号

如果您有一个GPU内存层次结构模型,该模型同时包含逻辑物理空间,例如一个

参考“概览选项卡”图:

  • gld_事务是指从以全局逻辑空间为目标的warp发出的事务。在图中,这是从左边的“内核”框到右边的“全局”框的一条线,逻辑数据的移动方向是从右到左

  • gst_交易指的是与上述相同的行,但逻辑上是从左到右。请注意,这些逻辑全局事务可以在缓存中命中,然后再也不会去任何地方。从度量的角度来看,这些事务类型只引用图表上的指示行

  • dram_write_事务指的是图中连接右边设备内存和二级缓存的那一行,逻辑数据流在这一行上是从左到右的。由于二级缓存线是32字节(而一级缓存线和全局事务的大小是128字节),因此设备内存事务也是32字节,而不是128字节。因此,通过L1(如果启用,则为直写缓存)和L2的全局写事务将生成4个dram_写事务。这应该可以解释40笔交易中的32笔

  • 系统内存事务以零拷贝主机内存为目标。你好像没有,所以我无法解释

  • 请注意,在某些情况下,对于某些GPU上的某些度量,当启动非常少量的线程块时,探查器可能会有一些“不准确”。例如,某些度量是在每个SM的基础上进行采样和缩放的。(但是,设备内存事务不在此类别中)。如果您在每个SM上做的工作不同(可能是因为启动了非常少的ThreadBlock),那么缩放可能会产生误导/不太准确。通常,如果启动的线程块数量较多,这些线程块通常会变得无关紧要


    也可能有兴趣。

    谢谢您的回答。这个数字有点帮助。但我仍然有一些问题。所以我不明白为什么这段代码有4个系统内存事务,其余的dram写事务来自哪里?这是一个非常直截了当的代码,所以我不希望有任何未知的事务!试图解释1扭曲的计数器是危险的。GPU有多个引擎和执行单元与着色器同时运行。随着计数器距离SM越来越远,过滤计数器的能力降低,您可以看到这些其他单位的增量。我建议启动1个扭曲的SM计数块和2个1个扭曲的SM计数块,并查看计数器是否相应缩放。
               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