Chinaunix首页 | 论坛 | 博客
  • 博客访问: 407751
  • 博文数量: 48
  • 博客积分: 764
  • 博客等级: 上士
  • 技术积分: 1133
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-17 13:29
文章分类

全部博文(48)

文章存档

2014年(5)

2013年(34)

2012年(9)

分类: LINUX

2013-02-19 18:09:47


Architecture

Pipeline

Divide a request to parts, then process through pipeline style will accelerate the efficience of CPU. If they didn't need a service in all stages, just pass by it. That efficient pipeline operation requires every stage to take the same amount of time. What make pipeline inefficient, various instructions itselves. Caching is in order to  make the instructions that need reference a variable in RAM use the equivalent time with other instructions without RAM.

MIPS vs CISC

All instructions are 32bits long: it means that load an arbitrary 32-bit value requires a two-instruction sequence!

The 32 registers.

No condition codes.

Register zero is always zero.

Memory references are always plain register loads and stores.

No byte or halfword arithmetic.

Minimal subroutine support. Jump and stores the return address into register$31.

Branch delay slot, the instruction position following any branch instruction.

Load delay slot


In general, a CPU architecture consists of an instruction set and some knowledge about registers. The terms instruction set and architecture are pretty close to synonymous, and you can get both at once in the acronym ISA


Exception interrupt

Mips异常被称为Precise excetpion。需要一些条件:

Unambiguous proof of guilt:我觉得很拗口,就是epc 记住victim指令的地址。如果victim是branch delay solt,epc指向前面的branch,cause bd置位。

Exceptions appear in instruction sequence:x86中断要在指令完整执行后,触发,而mips不是,这就会有问题。有个pipeline stage 用来detect exception。批评问浙江不是吃中中中

Subsequent instructions nullified:不会对后续指令有影响。


Vectored interrupt: cisc cpu会用hardware 分析exception,分发到不同entry point上,x86的idt就是这个功效。

vectored interrupt并不像想象中那么好用。现代操作系统比如linux会共享interrupt handler代码,比如do_IRQ()就是。而CISC 架构会好事的把选择不同的入口点,x86的idt就是这么回事。之后又从入口点跳到一个common handler do_IRQ是也。还记得x86那个interrupt数组吗?这也是耗时的。

另外,硬件本身分析exception也是一件难事。相比RISC机器就简明很多。

Polled interrupt: 

Mips中会分出多个入口点reset, tlb refill,  NMI,cache error, General 这么做的原因是为了提升性能,在kernel完全启动后 这些入口的地址ebase会重新点位到cached region,这也是为了性能。

有两种值得关注的异常tlb以及外设中断。我怎么觉得这都说烂了,原因在于他们发生频繁。

Coprocessor

cp0 system control processor 这个东西在x86下是没有的,或着说相同功能的microcode,没被明确的指认出来。在我看来cp0本质上就是一堆registers的集合而已。这也是他功能的体现。

CPU configuration:config config1-3

Cache control:

Exception/interrupt control:k0 k1 Cause  EPC SR EBASE InCtl

Memory management unit control: 

Miscellaneous:

CP0 Hazards—A Trap for the Unwary:简而言之就是流水线惹得祸,和Branch delay Data dlelay 一回事儿。解决方法还是nop、 ssnop(spurescalar nop)。

Execution hazards are those where the dependent instruction will not be affected until it reads a CP0 register value; 

Instruction hazards are those where the dependent instruction is affected in its very earliest stages—at worst, at the time it is fetched from cache or memory.

Mips 有一个supervisor mode,几乎用不到 怎么来的呢?原来DEC认为两级mode不安全,mips就加了一个,真正的真相是DEC想用自己的Alpha架构而不是mips,找的借口。可是alpha要比同一代的mips晚了18个月。

cp1 floating-point coprocessor

CP2 is available and occasionally used for custom ISA extensions or to provide application-specific registers in a few SoC applications. 

Cache

为什么会有cache这个东西,局部性引起的。无外呼空间和时间局部性。

cache本质上就是内存的翻版,好嘛。说到内存会有虚拟内存和物理内存之分。然而cache则没有,总算省点心了。实际上更闹心为什么?cache和内存之间,玩的是转化的游戏,内存可以分别通过虚拟、物理地址访问,而cache呢?再看cache本身,核心目的还是为了存储数据,关键在于如何定位这些数据。还是前面说的地址问题,一言以蔽之,cache设计的核心乃地址访问!

The direct-mapped arrangement or one-way set associative 

我们先不管虚拟还是物理地址来定位cache里的数据,cache定位设计思想是把一个地址分成3部分高中低。把cache想象成一个数组,就跟内存一样但小很多。有点类似中序遍历,地址的中部就是这个cache 数组的下标。插一句,cache的总大小=中部地址总数 × 低端地址大小(这个就是cache line size,不懂?)。当然内存中部相同的地址,海了!也就是高端地址不同但中部地址相同的所有地址都会被映射cache数组同一个下标下,狼多肉少。所以数组除了存真正从内存里得到数据还要存高端地址。至于那个低端地址的用途,比如cache line size 是4kb时,你想从这4kb中得到一个4b的数据,下端地址就是用来定位这个数据啦。这就是单路组相连映射,简单不过有个致命缺陷,会产生抖动cache thrashing,就是上面描述的高不同中相同的地址,在短时间内反复引用,一个进一个出。我们来看看这个单路组相连的名字,one-way set是一起的 one-way 相当形容词修饰set,只有一行的组,后面associative说的是cache和内存之间的关系—— 相关连,被称为content-addressable,什么意思?这里content指的是那个和数据一起存储的高端地址,用他来鉴别!至于组是什么,看一个就明白了。特别说一下,计算机黑话中上面的高端地址地址叫做tag,中部地址叫index。

Tow-way set associative

因为上面单路的组会产生 cache thrashing, 一个简单的方法就是中部地址对应的不再是cache line,升华了,是一个组,能装下两个cache line,上面的组被抹杀了,不那么明显了。实际上只能装一个cache line,要你有何用。所以两路的也很简单,在一定程度消弱了cache thrashing。注意,这里需要的地址中部的位数就要少相比单路,高位的增多了。

N-way set associative

一次类推就得到了,换汤不换药的坑爹n路组相关。

Fully associative

最坑跌的来了,整个cache成了一个组!!!这和单路有什么区别?别慌,随着组数的减少,需要的地址中部的位数也就越来越少了,到这里就是零了。也就是除了地址地位之外都是高位都要村到cache 中当content,很浪费呀。有两个好处1 抖动颠簸减到最小。 2 如果一段时间内引用的数据小于整个cache的大小那么性能就起来了。显然致命的缺陷,每次查cache都要从头到位搜,所以这决定了Fully associative不能太大,用在TLB上。


i-cache & d-cache

一句话,还是为了提升性能,关键词并行。


开胃菜还好,回头说说真正主角——地址。

从上面的描述,我们可以看到cache用到做鉴别数据的只有高端地址tag 和中部地址index。所以一切就有了头绪。

地址分为两类,虚拟和物理。而每类地址都可以分出tag 和index,有组合关系可得4中情况。为什么这么事B呢?随便找两个不久好了嘛。

VTVI:如果说只使用虚拟地址做tag 和index 就会出歧义ambiguit和别名alias问题。

先说ambiguit歧义,我们知道虚拟地址是动态映射的,那么一个虚拟地址可能先后先后被映射到两个不同的物理地址。那么之前映射是引用的数据保存在cache中,当新的映射建立后引用这虚拟地址数据就出问题了,因为cache中的数据是先前另一个物理地址存在的数据,被直接返回了。这就是由一个进程在时间错位造成的cache歧义。所得非所指!

alias别名,一个或两个进程用两个不同的虚拟地址映射同一个物理地址,可能被cache到不同的位置,就会出现数据的不一直。也就是说内存中数据在cache中有两个副本!

way size = cache size / N (N是上面的路数) 表示在一路的情况下,所有组的大小。 自己体会吧,我说不准。当way size 大于page size 就可能可会发生alias

另外,进程的用户空间的地址是重叠的,如果两个进程引用相同地址的数据就会出问题,和一个进程的歧义本质相同。你要吃苹果却吃了别人的香蕉。所以切换进程时内核会flush一下cache 和tlb。为了减少flush带来的性能消耗,通常在cache中加入一个key,通常是进程pid。

PTVI:为了解决歧义,通常用物理地址做tag地址,如果使用虚拟地址做index还有alias的问题。需要MMU物理地址转换。

PTPI:全部使用物理地址就一了百了了,可是需要MMU虚拟转物理,也要耗时。

VTPI:如果你在期待这种组合,说明你是白痴。

你看是不是很麻烦。x86是由硬件管理cache 对os透明的,为什么mips不这么做呢?貌似当时设计人员太冲动了。太激进了!PTVI是MIPS架构通用的选择,所以Alias这个魔鬼一直困扰linux社区。cpu_has_dc_aliases,内核用这个量表明是否有alias的问题。解决方法就是在可能alias的函数中flush cache。 那么怎么确定alias的位置呢?参见 内核文档cachetlb.txt

TLB

The TLB is what is called an associative or content-addressable memory—an entry is selected not by an index but by its contents. 就是上文提到的Fully associative。TLB通常比较小16-64项。对于4KB page 就是512KB,每一项可以存两个物理地址。




sentinel
















阅读(2488) | 评论(0) | 转发(0) |
0

上一篇:Functional language

下一篇:Kernel —— Hacks

给主人留下些什么吧!~~