Computer Architecture I
本博客所有知识均总结归纳于《Computer Orgnazition & Design The hardware/software Interface》,David A. Patterson and John L. Hennessy。
1.Performance
CPI=Average clock circles per Instruction (lower is better)
IPC=Average Instruction per clock circle (higher is better)
但是日常使用中,无法单纯的提高IPC而不影响时钟周期。
2.Register basic knowledge
2.1 load
从memory提取数据到register的操作被叫做load。通常load命令的组成为:load指令的名字+被load的register的名字+constant+去访问memory的register的名字。在MIPS中用lw表示load,load word的缩写。2.1.1 Example
例如c语言: g=h+A[8]
编译器会先编译指令去寻找A[8]的值,假设A的起始地址存储在寄存器$s3上并且地址间隔为1,计算机用以下指令去寻找A[8]:
lw $t0, 8($s3) //$t0为临时寄存器
然后在用$t0去与存储h的寄存器相加。
2.2 MIPS Memory Address
MIPS中用alignment restriction来限制每个字的长度为4byte,所以Memory Address必为4的倍数。
寻址方式有两种: leftmost(Big end) or rightend(little end)
2.3 store
store指令与load正好相反,它从register取值存储到memory。组成与load类似:store指令的名字+被store的寄存器(待被取出数值的寄存器)+memory地址偏移量(如A[8]就需要便宜4*8个偏移量)+基址寄存器(存储memory初始地址的寄存器)
store指令在MIPS中简写为sw, store word。
2.3.1 Example
例如C语言: A[12]=h+A[8]
编译器会将此命令分解为一下步骤,假设A的初始地址存在$s3中:
首先 load A[8]:
lw $to, 32($s3)
然后将临时寄存器t0的值与存储h的$s2相加:
add $t0, $s2, $t0
最后将$t0的新值store到A[12]中
sw $t0, 48($s3) //寄存器被store指令使用,所以仍然是寄存器写在前
2.3.2 Harder Example
C语言: g = h + A[i]
编译器会将此语句按一下步骤编译:
首先将i转换为地址的位移(4的倍数),计算机需要两步实现,假设i的初始值存储在$s4:
add $t1, $s4,$s4 // t1=i+i;
add $t1, $t1,$t1 // t1=2i+2i
假设A的此时地址存储在$s3中:
add $t1, $s3,$t1 // 得到A[i]的地址,4i+s3
然后读取A[i]的值:
lw $t0, 0($t1)
最后将A[i]与存储h的寄存器$s2相加:
add $s1 ,$s2, $t0 //g=h+A[i]
2.4 Spilling
在很多程序中,变量的个数要远远多于register的数量,所以对于计算机来说,有必要将最高频出现的变量存储在寄存器中,而将其他一些不常用的变量存在memory中。将低频使用的变量放进memory的过程叫做Spilling registers。
由于计算机关于speed与size的hardware principle,register会比memory更快因为register更小。所以从register中access data要比memory中快很多。
register有着比memory更快的访问速度、更高的throughput(吞吐量),所以为了达到最佳性能,我们必须高效使用register。
3. Instructions
3.1 Structure of Instructions
Instruction在计算机中的实际表现就是一串数字,而数字又被以高低电信号的方式保存在计算机中,所以可以简单理解Instruction就是由一群二进制数组成的长段数据。
几乎每个Instruction都需要对Register进行操作,所以大部分Instruction的组成中都含有特定的某些部分属于Register的编码。在MIPS assembly language中register $s0到$s7对应十进制数字16到23,临时register $t0到$t7对应十进制数字8到15。
3.1.1 Example
以 add $t0, $s1, $s2为例:
以十进制来表示此Instruction的Machine Instruction:
0-17-18-8-0-32
以二进制来表示:
000000-10001-10010-01000-00000-100000
3.1.2 Basic MIPS Fields 1
MIPS Fields用一种很简单的方式来组成Machine Instruction:
op - rs - rt - rd - shamt - funct
op: Operation对应的编码 6bits
rs: 第一个被operate的register 5bits
rt: 第二个被operate的register 5bits
rd: 目标register 5bits// 如3.1.1中的$t0, 数据最终被保存在t0
shamt: 移位 5bits
funct: Function, funct的编码从op code中选出适用于此次操作的具体功能 6bits
3.1.3 Basic MIPS Fields 2
上述3.1.2的结构并非适用所有情况,比如load指令中,如若用到数组,需要对数组进行寻址操作,往往6bit的大小不足以覆盖所有数组的地址,此时需要一种新的结构: op - rs - rt - address
其中,address占据16bits,op+rs+rt共16bits,所以Machine Instruction的总位数不变,仍为32bits,但是由于address占据16bits,几乎可以覆盖足够的数组。
3.2 Making Decisions
区分一个计算机和普通的计算器的重要依据就是这个机器是否有能力去做决定,也就是根据input与不同的条件,去执行不同的instructions,在C语言中常用的就是IF语句。
3.2.1 "Go to" example
MIPS instruction:
beq register 1, register 2, L1
其意思为:当register 1 与 register 2 的值相等时,执行L1。
MIPS instruction:
bne register 1, register 2 ,L1
其意思为:当register 1 与 register 2 的值不等时,执行L1。
C语言:
if( i==j ) goto L1;
f= g+h;
L1: f = f - i;
将其转换为Instruction后为:
beq $s3, $s4, L1 //if i 与 j 相等,执行L1
add $s0, $s1,$s2 //如果i与j相等,此instruction会被跳过
L1: sub $s0,$s0,$s3 //f = f - i
3.2.2 "if else"Harder example
C语言: if (i == j)
f = g + h;
else
f = g - h;
在此我们将讨论一个问题,若像3.2.1中一样,将else视为L1然后写下instructions,是否可以?
答案是否定的,倘若 i 与 j 不相等,依据3.2.1中的instruction,最终还是会执行L1,从而丧失做决定的能力。所以,在MIPS中有一个jump instruction,简写为j,此语句作用为跳跃至指定语句。
所以在“if else”中, 只需加入 j exit,结束程序的执行即可。
综上所述,将此C语言转换为MIPS Instruction后应为:
Comments
Post a Comment