体验cache

 

今天看了Peter Van Der Linden大师的关于cache优化的一段讲解,其中的程序作了改动展示如下:

// cache.cpp : 定义控制台应用程序的入口点。
//

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

# define SMARTCOPY memcpy(destination, source, 65536)
# define DUMBCOPY for(i = 0; i < 65536; i++) destination[i] = source[i]

int _tmain(int argc, _TCHAR* argv[])
{
 clock_t begin, end;
 double  cost;
 begin = clock();//计时函数,头文件time.h,精确度ms,好用。

 char source[65536], destination[65536];
 int  i,j;
 for(j = 0; j < 1000; j++)
  DUMBCOPY;
  //SMARTCOPY;

 end = clock();
 cost = (double)(end - begin) / CLOCKS_PER_SEC;
 printf("%lf seconds\n", cost);
 //system("pause");

 begin = clock();
 for(j = 0; j < 1000; j++)
  //DUMBCOPY;
  SMARTCOPY;
 end = clock();
 cost = (double)(end - begin) / CLOCKS_PER_SEC;
 printf("%lf seconds\n", cost);
 system("pause");

 return 0;
}

原书的解释如下;

编译并记录上面程序的运行时间,采用两种方式.第一种就是上面的程序,第二种就是用DUMBCOPY宏替换上面程序中的SMARTCOPY宏.我是在SPARCstation2上运行这个程序的,使用笨拷贝(dumpcopy)的程序的性能有显著的下降.
之所以出现性能下降,是因为source和destination的大小正好都是Cache容量的整数倍.SS2上的Cache行并不是按顺序填充的---它使用了一种特别的算法,填充于同一Cache行的主存地址恰好都是该Cache行大小的整数倍.这是由于对标签存储的优化所引起的--在这种设计方法中,只有地址的高位才被放入标签中.这样一来,source和destination便不可能同时出现在Cache中,于是导致了性能的显著下降.
在这个source和destination都使用同一Cache行的特殊情况下,会导致每次对内存的引用都无法命中Cache,使CPU的利用率大大降低,因为它不得不等待常规的内存操作完成.
库函数memcpy()经过特别优化以提高性能.它把先读取一个Cache行再对它进行写入这个循环分解开来,这就避免了上述问题.

这个解释我不是很理解,因为即使memcpy()这个函数即使不是copy 的64k它的运行速度依然会比for循环快的多。 当然这里不是争论这个的问题。

这里memcopy()把先读取一个cache行再对它进行写入.

memcpy在汇编上是使用stosb指令,而tosb指令是cpu内部指令,执行stosb指令时系统可以保证用户不需要作任何中间工作,系统完全有理由先把缓存填充满然后再写进目标地址中。而for循环是N多指令的结合,指令上memcpy就省了好多。而且由于rep stdsb指令是CPU内置指令组合,所以CPU懂得如何去高效地加载数据。
for循环每次都是复制1个字节,小于缓存容量,所以缓存不能够充分利用(印象中好象是32个字节),因为用户过程的介入,所以指令一旦写成CPU是无法优化的(区别与编译期优化)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值