int numberOfRows = matrix_n; int numberOfCols = matrix_n; int** mat1 = new int* [numberOfRows]; // a矩阵的行数 int** mat2 = new int* [numberOfRows]; int** mat3 = new int* [numberOfRows]; for(int i=0; i 初步测试:

现在将矩阵乘法的循环的潜逃次序改变一下,改写为一个新的函数,两个函数对比如下:

1.matrix_multiply_ijk版本:

// 计算矩阵乘法 ijk
void matrix_multiply_ijk(int **a, int **b, int **c, int n)  // n表示方阵的阶数 
	for(int i=0; i<n; i++)
		for(int j=0; j<n; j++)
			int sum = 0;
			for(int k=0; k<n; k++)
				sum += a[i][k]*b[k][j];
			c[i][j] = sum;

2.matrix_multiply_ikj版本:

// 计算矩阵乘法 ikj
void matrix_multiply_ikj(int **a, int **b, int **c, int n)  // n表示方阵的阶数 
	for(int i=0; i<n; i++)
		for(int k=0; k<n; k++)
			int sum = 0;
			int j;
			for(j=0; j<n; j++)
				sum += a[i][k]*b[k][j];
			c[i][j] = sum;

性能测量:

3.通过在不同的维度下测试两个函数的运行时间:

c++测试代码运行时间的方法:通过像个的时钟数来测量;

在ijk的方法下:

ijk方法下的测量结果(单位:ms)  1st2nd3rd4thn=1006374n=300104909592n=500474492484469n=8002001210021702042n=120010615982196899703n=200063677627976269862551

在ikj的方法下:

ikj方法下的测量结果(单位:ms)  1st2nd3rd4thn=1005333n=30077798178n=500 328351 341359n=8001435141314231453n=12004901477848494694n=200021664215012196821947

可以看到。在ikj的方案下,矩阵乘法的运算速度较快,而且在矩阵阶数n越大的时候,这种差别越是明显。在计算矩阵乘法的过程中,三层的循环嵌套共有六种排列方式,虽然在每种嵌套方式下,都要执行同样数量的操作,但是花费的时间是不同的。这是因为在不同的嵌套方式下,改变了数据的访问模式,进而改变了缓存未命中的数量。最终影响了运行时间。

关于缓存未命中的简单理解:

简单计算机模型:

L1 一级缓存

L2二级缓存

R 寄存器

ALU算术逻辑单元

在程序开始运行时,数据都位于主存中,需要将参与运算的数据从主存移到寄存器再进行运算。如果需要的数据没有在一级缓存,而是在二级缓存,而需要将数据存二级缓存移动到一级缓存,这称为一级缓存未命中,当需要的数据没有在二级缓存中时,此时为二级缓存未命中,则需要将数据从主存移动到二级缓存,再移动到一级缓存。所以可以通过减少缓存未命中的数量,提高程序的运行效率。计算机会采取相应的策略。

完整代码:

#include <iostream>
#include <cstdlib> 
#include <ctime>
#include <time.h>   // 包含时间测量的函数 
using namespace std;
void matrix_multiply_ijk(int **a, int **b, int **c, int n);
void matrix_multiply_ikj(int **a, int **b, int **c, int n);
void matrix_print(int **a, int n);
int main(int argc, char *argv[])
	// 定义数组:
	srand(time(0));
	int matrix_n = 2000;     // 修改矩阵的阶数为不同的值 
	int numberOfRows = matrix_n;
	int numberOfCols = matrix_n;
	int** mat1 = new int* [numberOfRows];  // a矩阵的行数
	int** mat2 = new int* [numberOfRows]; 
	int** mat3 = new int* [numberOfRows]; 
	for(int i=0; i<numberOfRows; i++)
		mat1[i] = new int[numberOfCols];
		mat2[i] = new int[numberOfCols];
		mat3[i] = new int[numberOfCols];
	// 初始化矩阵  1-10之间的随机数 
	for(int i=0; i<numberOfRows; i++)
		for(int j=0; j<numberOfCols; j++)
			mat1[i][j] = 1 + rand()%(10-1+1);
			mat2[i][j] = 1 + rand()%(10-1+1);
	//matrix_print(mat1, matrix_n);    // 输出矩阵 
	//matrix_print(mat2, matrix_n);    // 输出矩阵 
	//matrix_print(mat3, matrix_n);
	double clocks_PerMills = double(CLOCKS_PER_SEC) / 1000.0;   // 常数,每秒钟包含的时钟数 
	clock_t start_time = clock();                            // 开始的时钟数 
	// 选择矩阵乘法方案 
	//matrix_multiply_ijk(mat1, mat2, mat3, matrix_n);        // 矩阵乘法
	matrix_multiply_ikj(mat1, mat2, mat3, matrix_n);
	double elapseMills = (clock()-start_time) / clocks_PerMills; 
	cout << "The routine run time: " << elapseMills << "ms" << endl;
	cout << "clock_perMils: " << clocks_PerMills << endl; 
	//matrix_print(mat3, matrix_n);
	// matrix_multiply_ikj(mat1, mat2, mat3, matrix_n);
	// matrix_print(mat3, matrix_n);
	// 释放内存 
	for(int i=0; i<numberOfRows; i++)
		delete mat1[i];
		delete mat2[i];
		delete mat3[i];
	delete mat1;
	delete mat2;
	delete mat3;
	return 0;
// 计算矩阵乘法 ijk
void matrix_multiply_ijk(int **a, int **b, int **c, int n)  // n表示方阵的阶数 
	for(int i=0; i<n; i++)
		for(int j=0; j<n; j++)
			int sum = 0;
			for(int k=0; k<n; k++)
				sum += a[i][k]*b[k][j];
			c[i][j] = sum;
// 计算矩阵乘法 ikj
void matrix_multiply_ikj(int **a, int **b, int **c, int n)  // n表示方阵的阶数 
	for(int i=0; i<n; i++)
		for(int k=0; k<n; k++)
			int sum = 0;
			int j;
			for(j=0; j<n; j++)
				sum += a[i][k]*b[k][j];
			c[i][j] = sum;
// 输出矩阵
void matrix_print(int **a, int n)
	for(int i=0; i<n; i++)
		for(int j=0; j<n; j++)
			cout << a[i][j] << " ";
		cout << endl;
	cout << endl;

----------------------------------------------------end--------------------------------------------------------

假设两个大小相同的方阵需要计算乘法:按照矩阵乘法的规则:先写一段矩阵初始化代码:#include &amp;lt;iostream&amp;gt;#include &amp;lt;cstdlib&amp;gt; #include &amp;lt;ctime&amp;gt;using namespace std;void matrix_print(int **a, int n);int main(int argc, c... void matrixXvector(float* destvect, float* srcmatrix, int srcmatrix_rownum, int srcmatrix_colnum, float* srcvect, int srcvect_size){ for(int row=0;row<srcmatrix_rownum;++row){
参考资料:https://zhuanlan.zhihu.com/p/146250334(矩阵行列计算次序按照的是链接中提供的最优次序) 很惭愧地说,之前矩阵相乘一直在调函数,从来没有自己实现过,自己是非计算机科班出身,感觉基础确实一般。所以今天试着写了个多线程矩阵乘法作为练习,看看计算效率如何,如有问题欢迎交流指正。这里矩阵用的是 vector<vector<int> > 表示,绝对的速度上应该是不如数组,这里仅用于验证多线程的加速。 #include<iostream.
【题目描述】 计算两个矩阵的乘法。n×m阶的矩阵A乘以m×k阶的矩阵B得到的矩阵C 是n×k阶的,且C[i][j] = A[i][0]×B[0][j] + A[i][1]×B[1][j] + …… +A[i][m-1]×B[m-1][j](C[i][j]表示C矩阵中第i行第j列元素)。 第一行为n, m, k,表示A矩阵是n行m列,B矩阵是m行k列,n, m, k均小于100。 然后先后输入A和B两个矩阵,A矩阵n行m列,B矩阵m行k列,矩阵中每个元素的绝对值不会大于1000。
编写一个矩阵运算系统,能够实现对矩阵的常规运算,基本要求包括: (1) 一维矩阵类,能预定义矩阵的长度或运行中动态定义矩阵的长度。通过运算符重载,该类需能实现一维矩阵的基本算术运算(加、减、乘、除等); (2) 二维矩阵类,该类可通过继承一维矩阵类修改获得,也可重新定义。二维矩阵类需能够自由定义矩阵的维度,并同时能实现二维矩阵的基本算术运算; (3) 两个类都必须同时包含打印函数,能清楚打印出当前矩阵的内容; (4) 两个类都必须含有重载的复制构造函数和复制成员函数。
并行程序设计这门课程的课程实验要求我分别使用串行,并行+分块算法,并行+分块+SSE指令集加速,CUDA等四种方法来计算矩阵乘法. 还真别说收获蛮大的. 我的配置是i5 3470+GTX660Ti 下面的表格是各种算法下的情况. 多线程+分块 多线程+分块+SSE 572.2(m...
void matrix_multiply(int a[][COLS], int b[][COLS], int c[][COLS]) { int i, j, k; for (i = ; i < ROWS; i++) { for (j = ; j < COLS; j++) { c[i][j] = ; for (k = ; k < COLS; k++) { c[i][j] += a[i][k] * b[k][j]; int main() { int a[ROWS][COLS] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int b[ROWS][COLS] = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}}; int c[ROWS][COLS]; int i, j; matrix_multiply(a, b, c); printf("Matrix A:\n"); for (i = ; i < ROWS; i++) { for (j = ; j < COLS; j++) { printf("%d ", a[i][j]); printf("\n"); printf("Matrix B:\n"); for (i = ; i < ROWS; i++) { for (j = ; j < COLS; j++) { printf("%d ", b[i][j]); printf("\n"); printf("Matrix C = A * B:\n"); for (i = ; i < ROWS; i++) { for (j = ; j < COLS; j++) { printf("%d ", c[i][j]); printf("\n"); return ; 以上是用 C 语言编写矩阵乘法的代码。