CPU扩展设计——分支预测
写在开头本文为笔者学习《超标量处理器设计》的一些理解,请学习时结合本书食用~超标量处理器设计分享
概述考虑我们在计组设计中未曾考虑的问题:如果跳转指令成功跳转,选择默认不跳转的我们需要清空流水线前面的指令,这种清空被称为跳转惩罚。但由于我们的设计是五层流水线,跳转级在第二级,我们只需要引入延迟槽,便不需要清空流水线前面的指令,使得这个问题得到了解决。
但现代CPU设计具有以下的特点:
流水线的深度往往较深,可以达到十几级,一次清空就要被浪费掉许多条指令。
流水线的设计采用超标量设计,一次取指取到大于等于两条指令。
处理器高并行。
这样的特点导致了这种惩罚已经不是可以通过延迟槽避免的了,并且单次惩罚损失10+条指令。
并且在现代编程中,if,for,while这些语句的出现并不稀奇,所以这种频繁的惩罚是我们不能接受的,我们就需要对跳转进行尽力的预测,让CPU的实际运行尽力接近于我们的预测,这就引入了今天的设计——分支预测。
预测内容方向我们需要预测现在摆在我们面前的这条分支语句会不会发生跳转。
目标地址我们需要预测现在摆在我们面前的这条分支语句如果真跳了,会跳到哪里?这里可能有一个 ...
Unix 记忆留存 (三)
这是该系列第三篇,也是最后一篇
前言本篇博客是笔者在学习Unix课程时所积累的学习笔记。希望对后来学习Unix的友友复习准备Unix的期末考试有帮助。
系统调用文件I/O引言基本文件I/O函数:open、creat、read、write、lseek、close术语:不带缓冲的I/O(指每一个read、write都调用内核中的一个系统调用),低级例程。
文件描述符一个非负的整数,一个结构数组的下标,进程打开的文件表项的下标。open、creat函数会返回一个文件描述符文件描述符0、1、2默认打开,分别对应于标准输入(键盘)、标准输出(显示器)、标准错误输出(显示器)文件。在unistd.h中定义为STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO
函数介绍open#include <fcntl.h>int open(const char *pathname, int oflag, [mode_t mode])返回值:若成功,返回非负整数,即文件描述符。一定是当前“进程文件描述符表”中最小未使用的描述符。出错返回-1。pathname:常量,文件 ...
Unix 记忆留存 (二)
这是该系列第二篇。
前言本篇博客是笔者在学习Unix课程时所积累的学习笔记。希望对后来学习Unix的友友复习准备Unix的期末考试有帮助。
UNIX体系结构
Shell编程意义1.将一些有用的命令组合变成实用工具。例如:12345ls -l | sed -n '/^d/p' //显示当前目录下的子目录$ vi lsdir //用vi打开lsdir$ sh lsdir //执行lsdir脚本$ chmod +x lsdir //为lsdir赋予执行权限$ PATH=$HOME/bin:$PATH //修改路径2.快速编写一些实用的软件例如写一个自己的cat命令:1234$ vi mycat //用vi打开mycat文件awk '{print NR, ": ",$0}' $1 //$1 为shell命令的第1个参数$ chmod +x mycat // ...
Unix 记忆留存 (一)
这是该系列第一篇。
前言本篇博客是笔者在学习Unix课程时所积累的学习笔记。希望对后来学习Unix的友友复习准备Unix的期末考试有帮助。
什么是UNIXUNIX是一类操作系统。
狭义理解,UNIX是一个分时操作系统的核心,控制和分配计算机资源(软硬件),协调各应用进程的运行。
广义理解,UNIX除了其核心外,还包括一些基本的工具,如编辑器、编译器、文件操作工具、文字处理工具等。
更广义地理解,UNIX还包括用户自己开发的各种工具软件。
UNIX的历史1965年,贝尔实验室参与由MIT和GE发起的一个计划:开发一个多用户、多任务、多层次(multi-user、multi-processor、multi-level)的操作系统MULTICS(MULTiplexed Information and Computing System)
1969年,MULTICS计划失败,贝尔实验室的工程师们退出该计划。 Ken Thompson将自己开发一款原本运行在MULTICS系统上游戏软件“Space Travel(星际之旅)”移植到GE-635的机器上(GECOS系统),但速度很慢,且GE-635的 ...
System Verilog语法记录
前言System Verilog作为Verilog HDL的升级,对于我们开发FPGA是有非常大的帮助的,可以大大减轻码量,减少错误的产生。
由于龙芯杯的缘故,我们小组在商议后决定使用System Verilog来开发CPU,所以在此重拾计组,学习System Verilog并记录,方便后续翻看和为后来人抛砖引玉。TIPS:学习这篇博客需要默认会Verilog HDL
logic对verilog的初学者来说,我们常常面临两种数据类型的选择——wire和reg,也常常纠结于在特定情况下选择哪一种数据类型比较合适的问题。
并且reg变量好像暗指用时序逻辑的触发器搭建的硬件“寄存器”,然而实际上,reg变量跟推断出的硬件没有任何关系,这种不一致也常常有着误导作用。
System Verilog使用更直观的logic关键字来描述通用的针对硬件的数据类型。我们将会看到你可以在过去verilog中用reg型或是wire型的地方用logic型来代替。编译器可自动推断logic是reg还是wire。
即logic是对reg,wire数据类型的改进,使得它除了作为一个变量之外,还可以被连续赋值、门单元 ...
Lab0实验报告
思考题Thinking 0.1首先陈述结论,执行cat Modified.txt的结果和第一次执行add命令之前的status不一样:
执行Untracked:
执行Modified:
在第一次执行add命令之前,README.txt刚刚被创建,我们并没有输入任何有关于它的git指令,因而它处于未跟踪状态。所以它会出现在未跟踪的文件一栏。在经历过对其进行的种种操作后,README.txt处于已经被跟踪但修改还未暂存的阶段,所以它会出现在尚未暂存以备提交的变更一栏。
Thinking 0.2Add The File: git add 文件名
Stage The File:git add 文件名
commit:git commit -m “message”
Thinking 0.31.代码文件 print.c 被错误删除时,应当使用什么命令将其恢复?
答:使用git checkout — print.c
2.代码文件 print.c 被错误删除后,执行了 git rm print.c 命令,此时应当使用什么命令将其恢复?答:使用 git ...
CPU扩展设计--AXI总线接口实现
前言同步/异步读介绍《CPU设计实战》有这样一句话:在大多数真实的计算机系统中,CPU通过总线与系统中的内存、外设进行交互,没有总线,CPU就是个“光杆司令”,什么工作也做不了。
也因此,我们需要在CPU上设计总线接口,让我们的CPU能与总线进行交互,不再是孤岛。
还记得我们在P3-P7设计的取指和取值吗?
我们的地址在本周期发出,指令或者值便可以在本周期取回。这是一种异步读。这种设计现在看来大大帮助我们减轻了CPU设计的负担,但是所谓凡事皆有利弊,这种设计也在另一方面加剧了FPGA板子资源的消耗。
FPGA板子上有各种IP核(固化好的Ram资源等),如果我们这样设计,我们的CPU将不能利用这些高速资源,而是会用触发器层层叠搭,搭出一个异步读的Ram,这种方式导致了资源的浪费和速度的降低。
这些IP核的读取都是同步读,即地址在本周期发出,数据返回在下一周期或者更后面的某一周期。
Sram接口优势也因此,我们在P8进行板级验证的时候,不得不对我们的CPU做出修改,实现了当时不知道名字,现在知道它叫Sram接口的一种总线接口。
这种接口表现为CPU地址本周期发出, ...
树状数组
问题模型问题提出有一个数组arr,下标从1到n,现在有w次修改,q次查询,修改的话是修改数组中某一个元素的值;查询的话是查询数组中任意一个区间的和。规模在50w左右
暴力解法修改直接修改数组对应元素,时间复杂度为O(1),查询时直接相加,时间复杂对度O(n),总复杂度为O(wn).
前缀和解法修改需要修改前缀和数组对应点后的所有值,时间复杂度为O(n),查询时只需一次查询,时间复杂度为O(1),时间复杂度为O(qn).
可见暴力解法和前缀和解法时间复杂度其实大差不差.
寻找新解法有没有一种做法可以综合一下这两种朴素做法,然后整体时间复杂度可以降一个数量级呢?有——树状数组。
树状数组思想假设一个C数组,弃掉0下标不用,对于该数组每个下标所存内容,由如下规则决定:将下标转为二进制表示,求出该二进制表示最低一个1所表示的值,记为lowbit:该下标所存内容为arr数组中的(下标-lowbit,下标]的内容。eg:6的二进制表示为(110),那么6的lowbit的二进制表示为10,即为2,所以下标6所存内容为arr数组中的(4,6]的和。
这样做的根据在哪里?我们以求前6项和举例: ...
C++不常见但很好用的Api整理
本帖持续更新
algorithm库全排列函数next_permutation()介绍对于next_permutation函数,其函数原型为:
123#include <algorithm>bool next_permutation(iterator start,iterator end)
当当前序列不存在下一个排列时,函数返回false,否则返回true(字典升序)
prev_permutation()介绍next_permutation() 是按照字典升序的方式生成的排列。当我们想以降序的方式生成排列时,可以使用 prev_permutation()
示例下一个排列的基准以当前容器的元素顺序为准
代码1234567891011121314151617181920#include<iostream>#include<algorithm>#include<vector>using namespace std;vector<char> arr;int main(){ arr.push_back('a& ...
正整数C++高精度模板
前置函数数学取模1234int Mod(int x,int mod){ return (x % mod + mod) % mod;}
比较大小1234567891011int cmp(string a, string b){ if (a.length() > b.length()) return 1; else if (a.length() < b.length()) return -1; else { if (a < b) return -1; else if (a > b) return 1; else return 0; }}
int转string123456void i2s(int& x,string& s){ stringstream ss; ss << x; ss >> s;}
高精度思路用代码模拟小学所学的竖式加/减将乘除转化为加 ...