CUDA编程实践-3

矩阵转置求解

实现了两个版本的转置。一种是没有进行内存优化,直接上gpu的版本。
一种是考虑访存优化,利用share-memory进行优化。

先把host端的代码粘出来:
host端代码:

   #include<stdio.h>
   #include <stdlib.h>

   #include <cuda_runtime.h>
   #include <helper_cuda.h>
   #define BLOCK 16

void checkMalloc(float *ptr){
      if(ptr ==  NULL){
          printf("malloc failed\n");
          exit(0);
      }
  }

void dealError(cudaError_t err){
      if(err != cudaSuccess){
          printf("%s\n",cudaGetErrorString(cudaGetLastError()));
      }

  }

  void initFloatVec(float *h_src, int row, int col){
      int i, j;
      for(i=0; i<row; i++)
      for(j=0; j<col; j++){
          h_src[i + j * row] = i;
      }

  }
void printFloatVec(float *h_src, int row, int col){
      int i, j;
      for(i=0; i<row; i++){
          for(j=0; j<col; j++)
              printf("%f ", h_src[i + j * row]);
          printf("\n");
      }
      printf("\n\n");
  }

int main(){
      //int row = 10, col = 8;
      int row = 4, col = 2;
  //  int row = 8, col = 8;
      int memSize = row*col*sizeof(float);

      cudaError_t err = cudaSuccess;

      float *h_src =  NULL;
      float *h_dst =  NULL;


      float *d_src =  NULL;
      float *d_dst =  NULL;


      dim3 threadsPerBlock(BLOCK, BLOCK);
      dim3 blocksPerGrid((row+BLOCK-1)/BLOCK, (col+BLOCK-1)/BLOCK);
        /* malloc */
      h_src = (float*)malloc(memSize);
      h_dst = (float*)malloc(memSize);
      checkMalloc(h_src);
      checkMalloc(h_dst);

      err = cudaMalloc((void**)&d_src, memSize);
      dealError(err);

      err = cudaMalloc((void**)&d_dst, memSize);
      dealError(err);
      /*init h_src*/
      initFloatVec(h_src, row, col);
      printFloatVec(h_src, row, col);
      /*transfer to device memory*/
      err = cudaMemcpy(d_src, h_src, memSize, cudaMemcpyHostToDevice);
      dealError(err);

      transposeOpt<<<blocksPerGrid, threadsPerBlock>>>(d_src, d_dst, row, col);

      err = cudaMemcpy(h_dst, d_dst, memSize, cudaMemcpyDeviceToHost);
      dealError(err);
      printFloatVec(h_dst, col, row);

native version

不利用share-memory,直接访global memory进行计算。这个版本比较好理解,不进行解释。
代码:

__global__ void transpose(float* src, float* dst, int row, int col){
      int Idx = blockDim.x *blockIdx.x + threadIdx.x;
      int Idy = blockDim.y *blockIdx.y + threadIdx.y;
      //(Idx, Idy) =>(1D coordinate), col priority.
      int indexIn = Idx + Idy * row;
      int indexOut = Idy + Idx * col;
      if(Idx < row && Idy < col){
          dst[indexOut] = src[indexIn];
      }
  }

utilize share-memory version

思路:每个sm处理一块数据,每个sm内的线程先将数据从global memory拷贝进share memory,然后在share memory中完成转置,接着传回主存。这里,难点是地址的计算。
如何理解呢?我也没有想到好的解释。直接上代码吧。建议画图理解。

TODO

矩阵转置相关的论文(拓展)

分类:
方阵的转置,矩形矩阵的转置。
out-of-place, in-place转置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值