cuda实现矩阵相加

cuda实现向量相加

博客最后附上整体代码

如果有说的不对的地方还请前辈指出, 因为cuda真的接触没几天

一些总结(建议看)

  1. cuda 并不纯GPU在运行程序, 而是 cpu 与 gpu 一起在运行程序, cpu负责调度, gpu 负责运算, cpu称为HOST , gpu 称为 DEVICE
  2. 记住三个东西 grid block thread ,关系分别是 grid 包含多个 block , block 包含多个 thread
  3. 一个block中thread个数选取一般为32的整数倍, 原因和warp有关, 有兴趣自行查阅
  4. 一个grid中block的个数选取和你的kernel函数以及thread数量有关, 举个例子, int a[1000] 加上 int b[1000] , 你的thread为64, 那么, block = 1000/64 = 16个合适
  5. __global__函数一般表示一个内核函数,是一组由GPU执行的并行计算任务,由cpu调用
  6. __host__一般是由CPU调用,由CPU执行的函数,
  7. __device1__一般表示由GPU中一个线程调用的函数

代码实现

引入

#include <stdio.h>
#include <cuda_runtime.h>

kernel函数

__global__ void
vectorAdd(float *a, float *b, float *c, int num){
        int i = blockDim.x * blockIdx.x + threadIdx.x; //vector is 1-dim, blockDim means the number of thread in a block
        if(i < num){
                c[i] = a[i] + b[i];
        }
}

int i = blockDim.x * blockIdx.x + threadIdx.x;

这句代码解释一下:

blockDim.x 表示block的size行数(如果是一维的block的话,即一行有多少个thread)

blockIdx.x 表示当前运行到的第几个block(一维grid的话,即该grid中第几个block)

threadIdx.x 表示当前运行到的第几个thread (一维的block的话.即该block中第几个thread)

画个图解释一下

比如上面这个图的话, ABCDE各代表一个block, 总的为一个Grid, 每个block中有四个thread, 图中我花了箭头的也就是代表着第1个block中的第0个thread.

那么 i = blockDim.x * blockIdx.x + threadIdx.x 就是指 i = 4 * 1 + 0

申请内存空间与释放

host中申请内存

float *a = (float *)malloc(size);
float *b = (float *)malloc(size);
float *c = (float *)malloc(size);

free(a);
free(b);
free(c);

device中申请内存

float *da = NULL;
float *db = NULL;
float *dc = NULL;

cudaMalloc((void **)&da, size);
cudaMalloc((void **)&db, size);
cudaMalloc((void **)&dc, size);

cudaFree(da);
cudaFree(db);
cudaFree(dc);

host中内存copy到device

cudaMemcpy(da,a,size,cudaMemcpyHostToDevice);
cudaMemcpy(db,b,size,cudaMemcpyHostToDevice);
cudaMemcpy(dc,c,size,cudaMemcpyHostToDevice);

上面的cudaMemcpyHostToDevice用于指定方向有四种关键词

cudaMemcpyHostToDevice | cudaMemcpyHostToHost | cudaMemcpyDeviceToDevice | cudaMemcpyDeviceToHost

启动 kernel函数

int threadPerBlock = 256;
int blockPerGrid = (num + threadPerBlock - 1)/threadPerBlock;
vectorAdd <<< blockPerGrid, threadPerBlock >>> (da,db,dc,num)

此处确定了block中的thread数量以及一个grid中block数量

利用kernel function <<< blockPerGrid, threadPerBlock>>> (paras,...) 来实现在cuda中运算

参考

https://zhuanlan.zhihu.com/p/345877391

https://docs.nvidia.com/cuda/cuda-c-programming-guide/

源码展示

#include <stdio.h>

#include <cuda_runtime.h>

// vectorAdd run in device
__global__ void
vectorAdd(float *a, float *b, float *c, int num){
    int i = blockDim.x * blockIdx.x + threadIdx.x; //vector is 1-dim, blockDim means the number of thread in a block
    if(i < num){
        c[i] = a[i] + b[i];
    }
}

// main run in host
int
main(void){
    int num = 10000; // size of vector
    size_t size = num * sizeof(float);

    // host memery
    float *a = (float *)malloc(size);
    float *b = (float *)malloc(size);
    float *c = (float *)malloc(size);

    // init the vector
    for(int i=1;i<num;++i){
        a[i] = rand()/(float)RAND_MAX;
        b[i] = rand()/(float)RAND_MAX;
    }

    // copy the host memery to device memery
    float *da = NULL;
    float *db = NULL;
    float *dc = NULL;

    cudaMalloc((void **)&da, size);
    cudaMalloc((void **)&db, size);
    cudaMalloc((void **)&dc, size);

    cudaMemcpy(da,a,size,cudaMemcpyHostToDevice);
    cudaMemcpy(db,b,size,cudaMemcpyHostToDevice);
    cudaMemcpy(dc,c,size,cudaMemcpyHostToDevice);

    // launch function add kernel
    int threadPerBlock = 256;
    int blockPerGrid = (num + threadPerBlock - 1)/threadPerBlock;
    printf("threadPerBlock: %d \nblockPerGrid: %d \n",threadPerBlock,blockPerGrid);

    vectorAdd <<< blockPerGrid, threadPerBlock >>> (da,db,dc,num);

    //copy the device result to host
    cudaMemcpy(c,dc,size,cudaMemcpyDeviceToHost);

    // Verify that the result vector is correct
    for (int i = 0; i < num; ++i){
        if (fabs(a[i] + b[i] - c[i]) > 1e-5){
            fprintf(stderr, "Result verification failed at element %d!\n", i);
            return 0;
        }
    }

    printf("Test PASSED\n");

    // Free device global memory
    cudaFree(da);
    cudaFree(db);
    cudaFree(dc);
    // Free host memory
    free(a);
    free(b);
    free(c);

    printf("free is ok\n");
    return 0;
}

原文地址:https://www.cnblogs.com/wangha/p/10803696.html

时间: 2024-10-08 23:44:23

cuda实现矩阵相加的相关文章

cuda_opencv 矩阵相加

实现矩阵相加 1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <opencv/cv.h> 4 #include <opencv/highgui.h> 5 #include <opencv2/opencv.hpp> 6 7 #include "cuda_runtime.h" 8 #include "device_launch_parameters.h"

矩阵相加

/* Note:Your choice is C IDE */ #include "stdio.h" #include<stdlib.h> #include<time.h> #define N 4 void main() { int a[N][N]; int b[N][N]; int z,x,c,d,p,i,j; for(c=0;c<N;c++) srand(time(0)); a[0][c]=rand()%10; printf("\n\n&qu

C++面向对象编程解决三阶矩阵相加减

/*此处用面向对象编程*/ #include<iostream> #include<string.h> using namespace std; class Matrices { private: int mat[3][3]; public: Matrices(); void input() { for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { cin>>mat[i][j]; } } } friend Mat

JAVA学习笔记-矩阵相加

package MyDuoWeiShuZu; public class Mycode { public static void show(int[][] c){ for(int j=0;j<c.length;j++){ for(int i=0;i<c.length;i++){ System.out.print(c[j][i]+"\t"); } System.out.println(); } } public static int[][] add(int[][] a,int[

cuda编程-矩阵乘法(2)

采用shared memory加速 代码 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <algorithm> #include <cuda_runtime.h> #include <device_launch_parameters.h> #include "functions.h" #define TILE_SIZE 16 __

cuda编程-矩阵乘法(1)

本方法采用简单的单线程计算每组行和列乘加运算 代码如下: #include <stdio.h> #include <stdlib.h> #include <iostream> #include <cuda_runtime.h> __global__ void matrixMulKernel(float *C, float *A, float *B, int width, int height){ int tx = blockIdx.x * blockDim.

c语言:矩阵相乘-矩阵相加 新手练习1

#include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> void main() {     int a[4][4];     int b[4][4];     int c[4][4];     int i,j,k,s,t,m,n;     srand(time(0));     for(i=0;i<=3;i++)         for(j=0;j<=3;j

CUDA 矩阵乘法优化

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 矩阵乘法是有实用价值的程序,我们会使用浮点数. 虽然矩阵乘法有点老套,不过因为它相当简单,而且也可以用来介绍一些有关 CUDA 的有趣性质. 矩阵乘法 为了单纯起见,我们这里以方形的矩阵为例子.基本上,假设有两个矩阵 A 和 B,则计算 AB = C 的方法如下: for(i = 0; i < n; i++) { for(j = 0

CUDA编程之快速入门

CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架构.做图像视觉领域的同学多多少少都会接触到CUDA,毕竟要做性能速度优化,CUDA是个很重要的工具,CUDA是做视觉的同学难以绕过的一个坑,必须踩一踩才踏实.CUDA编程真的是入门容易精通难,具有计算机体系结构和C语言编程知识储备的同学上手CUDA编程应该难度不会很大.本文章将通过以下五个方面帮助大家比较全面地了解CUDA编程最重要的知识点,做到快速入门: GPU架构特点 CUDA线程模型