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

原创 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为误差,如下所示。


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

java 多线程并行计算之矩阵乘法(星星笔记)

用java编写两个n阶的方阵A和B的相乘程序,结果存放在方阵C中,其中乘法用for编译制导语句实现并行化操作,并调节for编译制导中schedule的参数,使得执行时间最短。 方阵A和B的初始值如下...
  • XX_123_1_RJ
  • XX_123_1_RJ
  • 2014年09月15日 09:57
  • 2720

js数字计算 误差 解决方法

//加法函数,用来得到精确的加法结果 //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 //调用:accAdd(arg1,a...
  • merrylilili
  • merrylilili
  • 2017年01月23日 10:21
  • 855

BigDecimal处理小数计算误差

BigDecimal处理小数计算误差float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象。浮点数没有办...
  • QCkiss
  • QCkiss
  • 2017年03月29日 11:44
  • 573

数值计算误差

补充题在MATLAB上执行>> 5.1-5-0.1和>> 1.5-1-0.5,给出执行结果,并简要分析一下产生现象的原因代码:>> x1=5.1-5-0.1 x1 = -3.6082248300317...
  • u014525812
  • u014525812
  • 2016年05月11日 12:12
  • 361

<Python> Numpy中的矩阵乘法问题

最近参加的一个Program,主题是生物识别,其中的PCA/LDA特征值提取部分需要大量用到线性代数矩阵论的知识,但是稍不注意numpy中的乘法规则就很容易得到错误的结果,最终导致后续结果的崩盘,尤其...
  • cqk0100
  • cqk0100
  • 2017年07月27日 22:48
  • 2185

多线程编程-矩阵乘法

一、项目内容 1、利用Pthread 库编写程序实现多线程矩阵乘法 2、比较多线程与单线程计算的时间 二、项目环境 1、VMware Workstation Pro 虚拟机...
  • m15851813962
  • m15851813962
  • 2016年11月24日 10:37
  • 2593

华为OJ(矩阵乘法计算量估计)

描述 矩阵乘法的运算量与矩阵乘法的顺序强相关。例如:    A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵 计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需...
  • yiqiwangxi
  • yiqiwangxi
  • 2015年08月20日 22:28
  • 1406

numpy矩阵相乘@的用法

numpy矩阵相乘@的用法
  • dengyibing
  • dengyibing
  • 2017年11月28日 19:32
  • 270

高阶导数的运算法则 与 莱布尼茨公式

高阶导数的运算法则 与 莱布尼茨公式
  • phoenix198425
  • phoenix198425
  • 2017年11月27日 20:35
  • 241

以矩阵乘法为例,了解cpu cache对程序性能的影响

#include using namespace std; #define N 1000 int a[N][N] = {0}, b[N][N] = {0}, c[N][N] = {0}; int m...
  • A775700879
  • A775700879
  • 2013年09月16日 23:52
  • 2498
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:矩阵乘法中的高阶计算时间和计算误差问题
举报原因:
原因补充:

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