矩阵乘法中的高阶计算时间和计算误差问题

原创 2016年05月31日 14:03:03

主要探讨的有两个问题:

1、当矩阵维度为16*16,2048*2048时,可以计算出来(用全1矩阵进行测试),并且加速比大于1(GPU快),可是当矩阵维度提升到4096*4096时,此时会出错(计算不准确,显示器驱动程序已停止响应 并且已成功恢复 ,怎么解决?

2、先前测试了全1矩阵,现在改成随机数矩阵(包括小数和整数),16*16等矩阵都不能得到正确的结果,怎么办?

首先贴出多线程的矩阵乘法代码:

kernel程序:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>

#include "matrixMul.h"

#define BLOCK_SIZE 16

// 核函数
__global__ void MatrixMulKernel( double* Md, double* Nd,double* Pd,int WidthM, int WidthN)
{
        //计算Pd中的元素索引
        int Row = blockIdx.y * BLOCK_SIZE + threadIdx.y; //行
        int Col = blockIdx.x * BLOCK_SIZE + threadIdx.x; //列

        float Pvalue = 0.0;
        for (int k = 0; k < WidthM; k++)
        {
                Pvalue += Md[Row * WidthM + k] * Nd[k * WidthN + Col];
        }
        //每个线程负责计算P中的一个元素
        Pd[Row * WidthN + Col] = Pvalue;
}

// 矩阵乘法
void matrixMul( double* M,double* N,double* P,int WidthM, int WidthN, int HeightM, int HeightN)
{
        double *Md, *Nd, *Pd;

    //字节长度
        int sizeM = WidthM * HeightM * sizeof(double);
    int sizeN = WidthN * HeightN * sizeof(double);
    int sizeP = WidthN * HeightM * sizeof(double);    

        cudaMalloc((void**)&Md, sizeM);
        cudaMalloc((void**)&Nd, sizeN);
        cudaMalloc((void**)&Pd, sizeP);

        //Copies a matrix from the memory* area pointed to by src to the memory area pointed to by dst
        cudaMemcpy(Md, M, sizeM, cudaMemcpyHostToDevice);
        cudaMemcpy(Nd, N, sizeN, cudaMemcpyHostToDevice);

    dim3 dimGrid( HeightM / BLOCK_SIZE , WidthN / BLOCK_SIZE);
        dim3 dimBlock( BLOCK_SIZE,  BLOCK_SIZE);        

        MatrixMulKernel<<< dimGrid, dimBlock >>>(Md, Nd, Pd, WidthM, WidthN);

        cudaMemcpy(P, Pd, sizeP, cudaMemcpyDeviceToHost);

        //释放设备上的矩阵
        cudaFree(Md);
        cudaFree(Nd);
        cudaFree(Pd);

    cudaDeviceReset();

}

mex调用程序
system('nvcc -c matrixMul.cu  -gencode arch=compute_50,code=sm_50 -ccbin "E:\VS2012\2012\VC\bin"')
mex matrixMulCuda.cpp matrixMul.obj -lcudart -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\x64";

disp('2.Input two matrix:')

%A=rand(16);
% B=rand(16);

A=ones(4096,4096);
B=ones(4096,4096);

C_gpu =matrixMulCuda(A,B);

论坛链接:http://bbs.gpuworld.cn/forum.php?mod=viewthread&tid=10280&extra=page%3D1


第一个问题:当测试4096*4096的矩阵时,此时GPU的计算时间不仅超过了matlab的计算时间,更主要的时超出了GPU的设置时间(TDR一般为2s),测试需要打开nsight visual studio edition进行TDR的设置,至于如何设置,博客中可以找见。

第二个问题实际上是编程的一个低级错误,cuda是按列存储的,按列取出并计算,而matlab是按行来的,所以计算结果会出现很大分歧、很大误差,此时我们在调用矩阵计算函数matrixMulCuda(A,B)B之前,将其转置后再计算,或者直接变成matrixMulCuda(B,A)也可以,这样就可以和matlab的计算结果进行比对了。

在整数的计算上,是没有误差的(2048*2048随机矩阵)

浮点数的计算上,误差较小(2048*2048随机矩阵),F为误差,如下所示。


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

矩阵乘法的优化

题目地址:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1113 昨晚为了优化这个题目弄到2点多,今天一早就写博,我真是...

并行计算矩阵乘法

  • 2015-12-11 14:44
  • 1.36MB
  • 下载

java 浮点数值计算误差

问题 当我们运行如下函数时 public void test() { System.out.println(2.0-1.1); //=>0.8999999999999999 } 我们发现...

CUDA矩阵乘法计算

  • 2016-08-26 22:26
  • 15KB
  • 下载

矩阵乘法求运行时间

  • 2017-04-15 20:38
  • 1013B
  • 下载

矩阵乘法的MPI并行计算

1、问题描述矩阵乘法问题描述如下:  给定矩阵A和B,其中A是m*p大小矩阵,B是p*n大小的矩阵。求C = A*B。求解这个问题最简单的算法是遍历A的行和B的列,求得C的相应元素,时间复杂度O(mn...

矩阵乘法计算脚本代码(C#)

代码: using System; using System.Collections.Generic; using System.Windows.Forms; class Script { ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)