CSAPP y86-64实验
作者:互联网
仅自己可见
前两个都是热身,第三个是重头戏
但是第三个目前还没有什么头绪,先把前两个写一下记录一下想法
一开始没少折腾,因为下错成了archlab-32的代码,还因为版本不兼容折腾了半天
下对了以后依然折腾,
一个是重复定义的问题,需要加-Xlinker --allow-multiple-definition忽略
另一个是tcl tk的问题,得装上tcl-dev tk-dev才能可视化调试,装完告诉我有些对象不存在,上网一查deprecated,用正则批量作了替换,+还得用+
第一个任务是把三个C函数手动编译成y86-64代码
首先书上有一个模板给了用于测试的y86-64的框架如下
//伪指令指定代码位置
.pos 0
//设置栈地址
irmovq stack, %rsp
//执行main函数
call main
//停机
halt
main:
ret
.pos 0x200
stack:
然后就是往上面套了。
第一个C函数是从前往后相加单链表上的数值,和x86-64差不多,在sum.ys文件
第二个C函数是从后往前,在rsum.ys,这个要注意保存调用者的寄存器状态,用到pushq和popq
第三个C函数是拷贝数组到指定位置,在copy.ys,这个要注意没有iaddq可用,只能先把常数加载到寄存器
三个函数执行完都会在shell打印运行结果和寄存器、内存上的变化,自行查看%rax的返回数值是否对的上就行了,但是保存调用者状态这个就不太能直接看出来;内存上的变化除了第三题以外都是栈上的残留
第二个任务是用hcl实现iaddq指令,从书上翻练习5.3可以找到定义,仿照图5.18分析清楚六个阶段各自的过程然后去改hcl就行了
一开始没有想到会用来更新状态,又弄了半天可视调试,最后打开测试代码一看还要更新三个状态寄存器
14 # 1. fetch:
15 # icode: ifun <- M1[PC]
16 # rA: rB <- M1[PC+1]
17 # valC <- M8[PC+2]
18 # valP <- PC + 10
19 # 2. decode:
20 # valB <- R[rB]
21 # 3. execute:
22 # valE <- valB + valC
23 # 4. visit memory:
24 # 5. write back:
25 # R[rB] <- valE
26 # 6. update PC
27 # PC <- valP
第三个任务是优化流水线,等我来战
2022/04/01更新:
忙活了5个小时,前两个小时看书,后三个小时胡搞,目前拿到了20分
平均CPE从15.18优化到了9.49
反正没有时间限制,想寄就寄(不是),慢慢优化
一开始实现iaddq绝对没错,在hcl实现完修改程序,CPE 12.7,不在10.5以内没有分
不过是个好开头
后来打算改成no taken strategy又前前后后胡搞了一阵
结果看了看程序绝大多数跳转的情况押的没问题
然后改了开头的一个边角,让第一次jump不出错,12.7到12.55
蚊子肉也是肉
因为有一个统计正数个数的流程
一开始想位运算统计,后来发现没移位,寄
然后想实现conditional move,转了一圈发现ISA已经有了,就是套的IRRMOVQ的icode所以没有找到;改程序,一跑,得,因为指令多了关键路径长了反而更慢了
后来看到题目说明文档给的暗示想起11章的优化来,立刻展开循环
4x展开立即见效,一轮少7条指令效果显著
8x展开也很好,7x略胜于8x
8x往后效果就下降了
(cpp生成展开,二分试的)
然后现在CPE 9.69,分数16.2
优化了一下开头冗余的两三条指令,分数到了20
现在满脑子想的是在ISA上加指令或者在原有指令上整活,比如加一个……
但是ISA好像是不能动的,只能优化流水线
或者在他的随机化算法上押宝,赌正数多还是负数多,程序是很难再找到大
的突破点了
update 实验时笔记原文
For part 3, it really gets bunches of necessary tests within it
My task is to make the CPE(Cycle per Element) lower than 10.50
better near 7.50
starting at 14.73
But i totally forgot the pipeline matter...
My resolution now:
. optimize the program to use iaddq
completed
prev: 63-ele -> 14.24, average 15.18
next: 63-ele -> 11.75, average 12.70
yet far from qualified
. implement iaddq and run benchmark
. optimize first jump
prev: 11.75, 12.70
next: 11.71, 12.55
not much
# . implement cmovq and optimize the program
cmovq has already been implemented but no use
# . take no-take policy when predicting PC (no need)
. loopUnrolling
it works!
reducing (12 - 5) instructions every 4 elements
can reach 8.70, 10.03, with 300 ~ 400 bytes
8 elements: 8.70, 9.69, with 400 ~ 500 bytes
7 elements: 0.1 point higher
2 redundant instructions saved -> 16.2 to 20.1
removed a redundant instruction that jugdes if %rdx > 0
-> 20.1 to 21.6
add another x4 unrolling loop
removed a redundant instruction
-> 21.6 to 24.4
optimize inner 4x unroll
-> 24.4 to 28.6
optimize for n == 1
-> 28.6 to 28.5/26.8
optimize iaddq $8, ...
-> 28.5 to 30.4
removed optimization for n == 1
-> 30.4 to 31.0
# . add a ciaddq based on cmovq
isa is already set
all these test stuff are to ensure no mod on isa behavior
# . modify iaddq behavior and replace old 'iaddq' with 'addq'
iaddq behavior is not forced to test
failed, not very efficient, e_Cnd seems not updated correctly
. keep thinking it like howmanybits
These days often late into night abnormally for playing...
Better get started on Fri. afternoon.
The PIPE design Always Takes the branch. In ncopy program,
since it just uses the branch when returning, i can take
Never Taken method. Plus cmovq
cmovq needs to fwd and Select $Cnd ?
标签:CSAPP,no,cmovq,y86,CPE,指令,64,iaddq,optimize 来源: https://www.cnblogs.com/StarOnTheWay/p/16079754.html