【操作系统】为什么转置512*512的矩阵比转置513*513的矩阵慢?

问题

操作系统课讲到内存管理部分时,老师谈到了cache技术,并且提出了一个问题:为什么转置512*512的矩阵比转置513*513的矩阵慢

我使用c语言进行了测试。程序代码附在文末,感兴趣的朋友可以自行测试。貌似在Linux上效果比较明显。

测试时为使效果明显,我将矩阵换成了1024*1024和1025*1025,测试结果如下:
在这里插入图片描述

可以看到经过多次测试,前者都比后者慢很多。显然是cache缓存命中率的问题。那么,到底如何使用cache解释这个现象呢?


解释

cache的结构有很多种,可以参考下面这篇文章,对cache的各种映像方法作了详尽的解释,写的很不错:https://www.cnblogs.com/east1203/p/11572500.html

同时,关于这个问题,我还参考了stack overflow上的一些优秀回答,如:https://stackoverflow.com/questions/11413855/why-is-transposing-a-matrix-of-512x512-much-slower-than-transposing-a-matrix-of

我这里采用2路组相连映像进行分析。假设cache每个缓存行可以存64个字节,4K个缓存行,每2个缓存行是一个set。在这种模型下,一共有4K/2=2K个set,主存地址每隔2K*64=128K个字节就会竞争同一个set

在本例中,512*512的数组,假设元素为4字节的int,那么一行就有512*4=2K个字节。因为每个缓存行为64字节,所以可以存下64/4=16个矩阵元素。

假设我们当前正在转置第i行的第0~第15个元素。这15个元素显然处于cache的同一个缓存行中。但是,这16个元素转置后需要放到第i列的第0~第15个元素,分处16个不同的cache的set中。

由于地址每隔128K(在矩阵中,相当于128K/2K=64行)就会竞争同一个set。这就意味着,i列0行、i列64行、i列128行等等元素会放在同一个set中。因此,当程序转置到第i列的第128个元素时,对应的set已经填满了(分别填了第0个元素和第64个元素的缓存行)。这时候,就要使用替换算法进行替换。类似的,访问到第i列的第129、第130……个元素时,都要进行替换。这相当于在按列访问时,cache一次都没有命中。因此很慢。

而在513*513的数组中,一行有513*4=2052个字节,并不能整除缓存行大小。这就恰好使得连续访问同一列的元素时,不会出现每64行冲突一次的情况。因此,访问速度相比上面快了很多。


附:测试代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N1 1024
#define N2 1025
int mat[N1][N1];
int mat2[N2][N2];

int main()
{
	srand(0);
	int i, j, temp;
	clock_t start_t, end_t;

	start_t = clock();
	for (i = 0; i < N1 - 1; i++)
		for (j = i + 1; j < N1; j++) {
			temp = mat[i][j];
			mat[i][j] = mat[j][i];
			mat[j][i] = temp;
		}
	end_t = clock();
	printf("%d*%d : %lf ms\n", N1, N1, (1.0 * end_t - start_t) * 1000 / CLOCKS_PER_SEC);


	start_t = clock();
	for (i = 0; i < N2 - 1; i++)
		for (j = i + 1; j < N2; j++) {
			temp = mat2[i][j];
			mat2[i][j] = mat2[j][i];
			mat2[j][i] = temp;
		}
	end_t = clock();
	printf("%d*%d : %lf ms\n", N2, N2, (1.0 * end_t - start_t) * 1000 / CLOCKS_PER_SEC);

	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值