冯诺依曼体系

mac2026-06-19  2

冯诺依曼体系:将程序指令和数据一起设计的计算机设计概念结构 必须有一个存储器、必须有一个控制器、运算器、输入设备、输出设备 冯诺伊曼瓶颈:存储器的速度跟不上CPU的速度,指磁盘、内存、寄存器。 程序翻译与程序解释 较为高级的计算机语言通过编译器生成较为低级的计算机语言。 1G->1024MB->10241024KB->10241024KB1024B(字节)->10241024KB1024B8bit(比特位)

存储器:CPU高速缓存、内存条、硬盘。 内存(RAM random access memory)通过电容来存储数据。 高速缓存在CPU中,主存即为内存,辅存即为磁盘。高速缓存解决CPU和主存速度不一致的问题。 高速缓存中存储CPU需要的数据。如果不存在,则需要去主存中读取。

高速缓存替换策略 1 随机算法(每次随机替换高速缓存中的数据) 2 先进先出(FIFO 把高速缓存看成一个队列,CPU执行替换时,将会将队头中数据淘汰,重复读取数据不会改变数据在缓存中的位置,) 3 最不经常使用算法(LFU(Last Fequently Used)优先淘汰不经常使用的数据,有一块区域会记录字块的使用频率,设计的数据结构可以为一个map,key为频率,value为该频率下的节点,即内存中的块) 4 最近最少使用算法。(LRU (Last Recently User),同样使用队列存储使用的数据,将使用的数据移动到队头,这样 ,使用次数多的一定在队头,执行淘汰策略的时候淘汰队尾的数据) LFU强调的是一段时间内的频率。 LRU强调的是一段时间内的使用次数。这两个算法不能划等号,比如某个缓存块之前一段时间的访问频率比较高,但是已经好久没被使用了,按照LFU算法,是会被淘汰的,同样,如果一个缓存块是新加入的,访问次数比较低,按照LFU是会被淘汰的,但是按照LRU算法是不会被淘汰的。

LRU算法实现 采用链表存储数据节点,每次将数据添加到数据队尾,链表中的数据如果被访问到了那么将该节点断开,添加到队尾,核心方法如下:

public int get(int key) { print(); Node node = this.tail; while (node != null) { if (Objects.equals(node.key, key)) { moveNodeToTail(node); return node.value; } node = node.before; } return -1; } /** * 将node节点添加到队尾 * @param node */ private void moveNodeToTail(Node node) { if (this.tail == node) { // 不用移动 return; } //node的前后不要指向node if (node.before == null) { //不存在前置节点 this.head = node.after; } else { node.before.after=node.after; } node.after.before = node.before; this.tail.after = node; node.before = this.tail; node.after = null; this.tail = node; } public void put(int key, int value) { print(); // 是否存在 Node node = this.tail; while (node != null) { if (Objects.equals(node.key, key)) { // 覆盖之前的值 node.value = value; moveNodeToTail(node); return; } node = node.before; } if (this.currNodeSize >= this.capacity) { // 发生淘汰策略 eliminateNode(); } Node putNode = new Node(key, value); if (this.currNodeSize==0) { // 为第一个节点 this.head = putNode; } else { // 不是第一个节点 putNode.before = this.tail; this.tail.after = putNode; } this.tail = putNode; this.currNodeSize++; return; } /** * 发生淘汰策略 */ private void eliminateNode() { Node node = this.head; // 移除个数 int eliminateNum = this.currNodeSize - this.capacity + 1; for (int i = 1; i <= eliminateNum; i++) { node = node.after; } if(node!=null) { if(node.before!=null) { node.before.after=null; node.before=null; } } this.head = node; this.currNodeSize = this.currNodeSize - eliminateNum; }

参考:https://blog.csdn.net/u013164931/article/details/82803298 部分图片摘自某课网。

最新回复(0)