冯诺依曼体系

冯诺依曼体系:将程序指令和数据一起设计的计算机设计概念结构
必须有一个存储器、必须有一个控制器、运算器、输入设备、输出设备
在这里插入图片描述
冯诺伊曼瓶颈:存储器的速度跟不上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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值