并行矩阵乘法的实现与对比,CPU单线程串行/CPU双线程并行/CPU,PPL并行库/GPU,C++AMP并发/GPU,C++AMP分组优化
如题,我会细讲部分代码和原理,保证各位能看懂。然后我没有使用类的方式来封装,各位复制代码可以随意进行自我使用,怎么方便怎么来。
头文件
先贴出头文件matrix.h大致看一下:
#pragma once
#include <iostream>
#include <amp.h>
#include <WinBase.h>
#include <cstdlib>
#include <amp_math.h>
#include <ppl.h>
#include <iomanip>
#include <thread>
#include <chrono>
using namespace std::chrono;
#define M_PI acos(-1)
#define Random(x) (rand() % x)
#define _point 1
#define _optimized 1
static const int TileSize = 16;
//*****************************************************************************
// 函数:std::vector<std::vector<float>> Rand_Matrix(std::vector<float>& V, const int row, const int col);
// 作用:生成随机矩阵
// 输入:V 需要插入随机数的矩阵,row行数,col列数
// 输出:另一个二维随机数矩阵
//*****************************************************************************
std::vector<std::vector<float>> Rand_Matrix(std::vector<float>& V, const int row, const int col);
//*****************************************************************************
// 函数:double MatrixMultiply(std::vector<float>& vC, const std::vector<float>& vA,
// const std::vector<float>& vB, int M, int N, int W)
// 作用:矩阵乘法 vC=vA*vB
// 输入:vC需要求得的矩阵,vA左乘的矩阵,vB右乘的矩阵,vA=(M,W),vB=(W,N),vC=(M,N),optimized的函数代表优化过的函数
// 输出:运行总时间
//*****************************************************************************
double MatrixMultiply(std::vector<float>& vC, const std::vector<float>& vA,
const std::vector<float>& vB, int M, int N, int W);
double MatrixMultiply(std::vector<float>& vC, const std::vector<float>& vA,
const std::vector<float>& vB, int M, int N, int W, bool optimized);
//*****************************************************************************
// 函数:double MatrixMul_Cpu(std::vector < std::vector<float>>& vC, const std::vector < std::vector<float>> vA,
// const std::vector < std::vector<float>> vB, int M, int N, int W);
// 作用:矩阵乘法 cpu上运行
// 输入:同上
// 输出:运行总时间
//*****************************************************************************
double MatrixMul_Cpu(std::vector < std::vector<float>>& vC, const std::vector < std::vector<float>> vA,
const std::vector < std::vector<float>> vB,int M, int N, int W);
//*****************************************************************************
// 函数:double MatrixMul_Cpu_double(std::vector < std::vector<float>>& vC, const std::vector < std::vector<float>> vA,
// const std::vector < std::vector<float>> vB, int M, int N, int W);
// 作用:双线程矩阵乘法 cpu上运行 DuOne与DuTwo为两个线程执行的函数 一个执行奇数行的运算 另一个偶数行
// 输入:同上
// 输出:运行总时间
//*****************************************************************************
void DuOne(std::vector < std::vector<float>>& vC, const std::vector < std::vector<float>> vA,
const std::vector < std::vector<float>> vB, int M, int N, int W);
void DuTwo(std::vector < std::vector<float>>& vC, const std::vector < std::vector<float>> vA,
const std::vector < std::vector<float>> vB, int M, int N, int W);
double MatrixMul_Cpu_double(std::vector < std::vector<float>>& vC, const std::vector < std::vector<float>> vA,
const std::vector < std::vector<float>> vB, int M, int N, int W);
//*****************************************************************************
// 函数:double Multi_thread_cpu(std::vector < std::vector<float>>& vC, const std::vector < std::vector<float>> vA,
// const std::vector < std::vector<float>> vB, int M, int N, int W);
// 作用:多线程矩阵乘法 cpu上运行 采用PPL库
// 输入:同上
// 输出:运行总时间
//*****************************************************************************
double Multi_thread_cpu(std::vector < std::vector<float>>& vC, const std::vector < std::vector<float>> vA,
const std::vector < std::vector<float>> vB, int M, int N, int W);
//*****************************************************************************
// 函数:void Print_Matrix(const std::vector<float>& v, int M, int N, bool p)
// 作用:显示矩阵四个角的元素
// 输入:v矩阵,M行数,N列数,p
// 输出:无
//*****************************************************************************
void Print_Matrix(const std::vector<float>& v, int M, int N, bool p);
//*****************************************************************************
// 函数:void Print_Matrix(const std::vector < std::vector<float>>& vC, int M, int N);
// 作用:显示矩阵四个角的元素
// 输入:vC矩阵,M行数,N列数
// 输出:无
//*****************************************************************************
void Print_Matrix(const std::vector < std::vector<float>>& vC, int M, int N);
头文件中的部分细节
1.随机矩阵的生成
C++可以通过取引用’&’ 的方式使得输入的参数改变,如参数
vector<float> &V
最后设置返回值是vector<vector<float>> OutPut_Matrix
那么就可以通过一个函数同时得到两个相同的随机矩阵,一个是一维的一个是二维的。
包括接下来的乘法运算也都有使用这个方法。
2.全局变量
#define M_PI acos(-1)
#define Random(x) (rand() % x)
#define _point 1
#define _optimized 1
M_PI
为圆周率。Random(x)
是简单定义了一个函数可以求得[0,x)的整数随机数,在随机矩阵函数中使用。
以下两个只是为了当参数在两个函数中使用。
3.cpu与gpu运算的输入不同
注意一下,cpu的输入矩阵为vector<vector<float>>
是二维的,而gpu是一维的vector<float>
4.一些初始化的定义
C=A*B
A大小是M*W
; B大小是W*N
; C大小是M*N
static const int TileSize = 16;
定义的是GPU AMP优化运算的分块大小,后续会讲
主程序入口main()函数
matrix.cpp
#include <matrix.h>
int main()
{
int M = 256, N = 256, W = 256;
std::vector<<