您的位置:首页 > 编程语言

CUDA编程实践-3

2017-03-16 17:08 267 查看

矩阵转置求解

实现了两个版本的转置。一种是没有进行内存优化,直接上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转置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cuda