一、一个工艺的问题
-
处理器和内存所使用的半导体期间工艺不同
V(处理器)>>>远大于>>>V(内存)
-
工艺的差异导致了处理器与内存的速度差异
-
数据处理时,处理器总是需要等待内存
二、程序访问的局部性
- 在短时间内,处理器访问的存储空间是一个很小的范围
- 时间局部性
- 某个存储单元在短时间内很可能被再次访问
- 空间局部性
- 某个存储单元的邻近单元在短时间内也被访问
- 时间局部性
三、高速缓冲存储器的引入(cache)
- cache是一种小容量高速存储器
- cache的存取速度与处理器的运算速度几乎同量级
- cache在现代计算机系统中直接内置于处理芯片中
四、cache解决方案
-
在处理器和内存之间设置cache
-
把内存中被频繁访问的指令和数据复制到cache中
-
大多数情况下,处理器能直接从cache中取得指令和数据
五、问题
内存和cache之间如何映射?
六、直接映射法
-
将cache和内存分成固定大小的块(如:512Byte/块)
-
内存中的每一块在cache中有固定的映射位置
-
映射公式为:
Pos(cache) = 内存块号 % cache总块数
地址划分:
标记 | 块内地址 | cache块号 |
---|---|---|
t位 | b位 | c位 |
映射原理:
- 根据访问地址的中间c位找到cache中的对应块
- 比较地址的高t位是否和flag相同
- 相同:直接读取数据
- 不同:从内存中固执块内容
例:当前处理器需要访问内存地址:0X0240CH
-
地址划分:
0000 001 0010 0 0000 1100 标记位 块号:块内起始地址 块内地址 -
根据0010直接访问cache中的第0010块
-
匹配第0010块的flag是否等于0000001
- 相等——访问0010块中1100处的数据
- 不等——从内存中读取块数据,更新cache
七、直接映射法的特点
- 优点
- 映射过程简单,所需耗时短
- 缺点
- 当短时间内访问的地址有同余冲突时,会造成缓存失效
八、cache原理的软件应用
-
项目背景:日志调试工具(Log Dog)
- 解决的问题:
- 日志对系统效率影响巨大,且不容易分析查看
- 现有的日志无法高效的打印二进制数据
- 自定义日志内容的解析方式
- 对日志进行分类,并控制日志是否输出
- 解决的问题:
-
出现的性能问题
- 当短时间内有大量日志需要打印时,性能无法满足调试需要
-
最终的解决方案
- 根据cache原理,设置二级缓存机制,尽量避开查找
message ==> type ==> int
每个工程师都可以自定义日志类型
自定义解析方式 ==> Lua Script
message ==> Lua Script(parser)
Script ==> id ==> int
void process(Message* msg)
{
static Parse* cache1 = NULL;
//二级缓存机制
static Parse* cache2 = NULL;
if((cache != NULL) && (cahe->id == message->type))
{
cache->handle(msg);
}
else
{
Parser* p = find_parser(msg->type);
if(p != NULL)
{
p->handle(msg);
cache = p;
}
}
}