内存访问

来源:互联网 发布:薛飞杜宪事件 知乎 编辑:程序博客网 时间:2024/06/01 22:17

1、访问内存的低性能主要原因

在于全局存储器,这种存储器通常通过动态随机访问存储器(Dynamic Random Access Memory实现,DRAM),在访问时有可能出现长延时(几百个时钟周期)和访问带宽有限的情况。

2、如何减少全局存储器流量的策略

一种常用的策略是把数据划分成多个子集,称之为块(tile),每个块都必须满足共享存储器的容量限制。

eg:矩阵乘法(通过线程间的合作来减少全局存储器中的流量)

基本思想是在对应的点积运算中单独地使用这些元素前,通过线程合作将Md和Nd中的元素加载到共享存储器上。

//使用共享存储器的分块矩阵乘法中的kernel函数
_global_void MatrixMulKernel(float *Md,float *Nd,float *Pd,int Width)
{
   _shared_float Mds[TILE_WIDTH][TILE_WIDTH];//共享存储
   _shared_float Nds[TILE_WIDTH][TILE_WIDTH];
   int bx = blockIdx.x; int by =blockIdx.y;
   int tx = threadIdx.x;int ty =threadIdx.y;
   
   //标识要处理的Pd元素的行和列
   int Row = by * TILE_WIDTH+ty;
   int Col = bx * TILE_WIDTH+tx;
   
   float Pvalue = 0;
   //循环Md和Nd中要计算Pd元素所对应的块
   for(int m=0;m<Width/TILE_WIDTH;++m)
   {
      //通过协作把Md和Nd的块加载到共享存储器中
 Mds[ty][tx]=Md[Row*Width + (m*TILE_WIDTH+tx)];
 Nds[ty][tx]=Nd[(m*TILE_WIDTH+ty)*Width+Col];
 _syncthreads();
 
 for(int k=0;k<TILE_WIDTH;++k)


        Pvalue+=Mds[ty][k]*Nds[k][tx];
_syncthreads();


   }
   Pd[Row*Width+Col]=Pvalue;
}

0 0