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

__global__ void matrixMulKernel(float *C, float *A, float *B, int width, int height){
    __shared__ float tile_A[TILE_SIZE][TILE_SIZE];
    __shared__ float tile_B[TILE_SIZE][TILE_SIZE];
    unsigned int tx = threadIdx.x;
    unsigned int ty = threadIdx.y;
    unsigned int gx = blockIdx.x * TILE_SIZE + tx;
    unsigned int gy = blockIdx.y * TILE_SIZE + ty;
    if (gx >= width || gy >= height)
        return;

    // Load shared memory
    int tile_num = (width + TILE_SIZE - 1) / TILE_SIZE;
    float sum = 0;
    for (int i = 0; i < tile_num ; ++i){
        int bound = min(width, TILE_SIZE);
        for (int j = tx; j < bound; j+=blockDim.x){
            tile_A[ty][j] = A[gy * width + i * bound + j];
        }
        for (int j = ty; j < bound; j += blockDim.y){
            tile_B[j][tx] = B[(i * bound + j) * width + gx];
        }
        __syncthreads();

        for (int j = 0; j < bound; ++j){
            sum += tile_A[ty][j] * tile_B[j][tx];
        }
    }
    C[gy*width + gx] = sum;

}

void constantInit(float *data, int size, float val){
    for (int i = 0; i < size; ++i){
        data[i] = val;
    }
}

void matrixMul(){
    int dev_id = 0;
    cudaSetDevice(dev_id);

    // Allocate host memory for matrices A and B
    int width = 128;
    int height = 128;
    unsigned int size = width * height;
    unsigned int mem_size = sizeof(float)* size;
    float *h_A = (float *)malloc(mem_size);
    float *h_B = (float *)malloc(mem_size);
    float *h_C = (float *)malloc(mem_size);

    // Initialize host memory
    const float valB = 0.01f;
    constantInit(h_A, size, 1.0f);
    constantInit(h_B, size, valB);

    // Allocate device memory
    float *d_A, *d_B, *d_C;
    cudaMalloc((void **)&d_A, mem_size);
    cudaMalloc((void **)&d_B, mem_size);
    cudaMalloc((void **)&d_C, mem_size);

    // Memcpy
    cudaMemcpy(d_A, h_A, mem_size, cudaMemcpyHostToDevice);
    cudaMemcpy(d_B, h_B, mem_size, cudaMemcpyHostToDevice);

    // Config dim
    dim3 block(TILE_SIZE, TILE_SIZE);
    dim3 grid((width + block.x - 1) / block.x, (height + block.y - 1) / block.y);
    matrixMulKernel <<<grid, block >>>(d_C, d_A, d_B, width, height);

    // Memcpy device to host
    cudaMemcpy(h_C, d_C, mem_size, cudaMemcpyDeviceToHost);

    // Check
    printf("Checking computed result for correctness: ");
    bool correct = true;

    // test relative error by the formula
    //     |<x, y>_cpu - <x,y>_gpu|/<|x|, |y|>  < eps
    double eps = 1.e-6; // machine zero

    for (int i = 0; i < (int)(width * height); i++)
    {
        double abs_err = fabs(h_C[i] - (width * valB));
        double dot_length = width;
        double abs_val = fabs(h_C[i]);
        double rel_err = abs_err / abs_val / dot_length;

        if (abs_err > eps)
        {
            printf("Error! Matrix[%05d]=%.8f, ref=%.8f error term is > %E\n", i, h_C[i], (float)(width*height), eps);
            correct = false;
        }
    }

    printf("%s\n", correct ? "Result = PASS" : "Result = FAIL");

}
时间: 2024-11-09 08:51:04

cuda编程-矩阵乘法(2)的相关文章

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.

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线程模型

CUDA编程之快速入门【转】

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

详解CUDA编程

CUDA 是 NVIDIA 的 GPGPU 模型,它使用 C 语言为基础,可以直接以大多数人熟悉的 C 语言,写出在显示芯片上执行的程序,而不需要去学习特定的显示芯片的指令或是特殊的结构." 编者注:NVIDIA的GeFoce 8800GTX发布后,它的通用计算架构CUDA经过一年多的推广后,现在已经在有相当多的论文发表,在商业应用软件等方面也初步出现了视频编解码.金融.地质勘探.科学计算等领域的产品,是时候让我们对其作更深一步的了解.为了让大家更容易了解CUDA,我们征得Hotball的本人同

CUDA编程(十)使用Kahan&amp;#39;s Summation Formula提高精度

CUDA编程(十) 使用Kahan's Summation Formula提高精度 上一次我们准备去并行一个矩阵乘法.然后我们在GPU上完毕了这个程序,当然是非常单纯的把任务分配给各个线程.也没有经过优化.终于我们看到,执行效率相当的低下,可是更重要的是出现了一个我们之前做整数立方和没遇到的问题,那就是浮点数精度损失的问题. 关注GPU运算的精度问题: 在程序的最后.我们计算了精度误差,发现最大相对误差偏高,而一般理想上应该要低于 1e-6. 我们之前将评估CUDA程序的时候也提过了.精度是CU

矩阵乘法的Strassen算法详解

题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B是n×p矩阵,它们的乘积AB是一个m×p矩阵,它的一个元素其中 1 ≤ i ≤ m, 1 ≤ j ≤ p. 值得一提的是,矩阵乘法满足结合律和分配率,但并不满足交换律,如下图所示的这个例子,两个矩阵交换相乘后,结果变了: 下面咱们来具体解决这个矩阵相乘的问题. 解法一.暴力解法 其实,通过前面的分析

基于OpenMP的矩阵乘法实现及效率提升分析

一.  矩阵乘法串行实现 例子选择两个1024*1024的矩阵相乘,根据矩阵乘法运算得到运算结果.其中,两个矩阵中的数为double类型,初值由随机数函数产生.代码如下: #include <iostream> #include <omp.h> // OpenMP编程需要包含的头文件 #include <time.h> #include <stdlib.h> using namespace std; #define MatrixOrder 1024 #def

【甘道夫】MapReduce实现矩阵乘法--实现代码

之前写了一篇分析MapReduce实现矩阵乘法算法的文章:[甘道夫]Mapreduce实现矩阵乘法的算法思路 为了让大家更直观的了解程序执行,今天编写了实现代码供大家参考. 编程环境: java version "1.7.0_40" Eclipse Kepler Windows7 x64 Ubuntu 12.04 LTS Hadoop2.2.0 Vmware 9.0.0 build-812388 输入数据: A矩阵存放地址:hdfs://singlehadoop:8020/wordsp