ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

计算机体系结构课后习题解析:指令系统、流水线与多核设计

计算机体系结构课后习题解析:指令系统、流水线与多核设计 1. 计算机体系结构这门课到底在讲什么1.1 从“造CPU”的视角重新理解计算机很多人第一次翻开胡伟武老师这本《计算机体系结构》的时候第一反应是“这不就是计算机组成原理的进阶版吗”。我当初也是这么想的直到真正把前几章啃完才发现完全不是一回事。计算机组成原理教你的是“一台计算机由哪些部件组成、它们怎么协同工作”而体系结构这门课的核心命题只有一个如何在工艺、功耗、成本的约束下设计出一颗真正能跑得快、跑得稳的处理器。胡老师这本书最大的特点是它不像很多教材那样从“指令集分类”开始讲而是直接从“指令系统设计”切入然后一路讲到流水线、存储层次、多核与并行。这个编排逻辑其实非常“龙芯”——因为龙芯团队本身就是从指令系统开始自研CPU的他们踩过的坑、做过的取舍全都渗透在教材的章节安排里。所以你在做课后题的时候如果只是把题目当成“计算题”来做那就浪费了这本书的价值。每一道题背后其实都对应着一个真实的工程决策场景。比如“为什么RISC指令长度要固定”“为什么流水线要分级”“为什么Cache要有多个层次”这些问题在考试里可能只值5分但在实际芯片设计里每一个都可能是几千万甚至上亿的研发成本差异。1.2 课后习题的三种类型与应对策略我把胡老师这本书的课后题大致分成三类这个分类是我自己做完三遍之后总结出来的不一定严谨但很实用第一类是概念辨析题比如“简述CISC和RISC的区别”“解释什么是流水线冒险”。这类题看起来简单但很多人答不全。我的经验是答这类题一定要先给定义再给对比维度最后给一个具体例子。比如答CISC和RISC的区别不要只写“CISC指令复杂、RISC指令简单”而要按指令长度、寻址方式、访存模式、控制器实现方式这几个维度展开每个维度用一两句话说明最后举一个x86和MIPS的实际指令对比。第二类是计算分析题比如“给定流水线级数和时钟周期计算加速比”“给定Cache命中率和访问时间计算平均访存时间”。这类题是考试的重灾区也是课后答案最容易出错的地方。因为计算题往往有多个公式变体不同教材的符号定义还不一样。我的建议是不要背公式要理解每个公式的推导过程。比如流水线加速比的公式本质就是“非流水线执行时间除以流水线执行时间”你把这两个时间分别写出来公式自然就出来了根本不用记。第三类是设计开放题比如“设计一个支持某类应用的指令系统”“分析某种存储层次方案的优劣”。这类题没有标准答案但恰恰是胡老师最看重的。因为龙芯的很多设计决策就是在这种开放讨论中形成的。答这类题的关键是先明确约束条件再给出方案最后分析取舍。不要一上来就写“我选择方案A”而要写“在功耗优先的约束下方案A比方案B更合适因为……”。1.3 为什么“最新版”课后答案值得单独整理网上流传的胡伟武课后答案有很多版本但大部分是学生手写的扫描件字迹潦草不说很多计算过程还有错误。更麻烦的是有些答案只给了最终结果没有中间步骤你根本不知道这个结果是怎么来的。我见过最离谱的一份答案流水线加速比那道题直接写了个“约等于3.2”连公式都没列。所以“最新版”这三个字的价值不在于“新”而在于“完整”和“可验证”。一份好的课后答案应该包含题目原文、解题思路、详细步骤、最终答案、以及必要的补充说明。尤其是补充说明比如“这道题如果改成XX条件答案会变成YY”这种延伸才是真正帮你理解知识点的关键。我整理这份答案的时候给自己定了一个规矩每一道计算题都必须能用手算复现每一道概念题都必须能用自己的话讲出来。如果做不到说明我还没真正理解这道题。这个规矩看起来很笨但效果很好——后来我在做实际项目的时候遇到类似的性能分析问题脑子里能直接调出这些题目的解题框架。2. 指令系统设计类题目的核心解法2.1 指令格式设计题的通用套路指令格式设计是胡老师这本书前几章的重点也是课后题里出现频率最高的一类。这类题通常给你一个指令集的需求描述比如“需要支持8条算术指令、4条逻辑指令、2条访存指令”然后让你设计指令格式。很多人拿到这种题就懵了因为感觉条件不够。其实这类题有一个非常固定的解题套路第一步统计指令总数。把题目里提到的所有指令加起来得到总指令条数N。比如84214条。第二步计算操作码位数。操作码位数 ceil(log2(N))。14条指令需要4位操作码因为2^41614。第三步分配地址码位数。根据题目给出的地址空间和寻址方式确定每条指令需要几个地址码、每个地址码多少位。比如如果地址空间是64KB那么每个地址码需要16位。第四步计算指令总长度。操作码位数 地址码位数之和。如果题目要求指令长度固定那就取所有指令中最长的那个如果允许变长那就分别列出每种格式的长度。第五步检查约束条件。比如题目可能要求“指令长度必须是字节的整数倍”那就要把计算结果向上取整到8的倍数。这个套路看起来简单但实际操作中有几个坑。第一个坑是操作码扩展。如果题目要求“短指令的操作码不能是长指令操作码的前缀”那就需要用扩展操作码技术。比如4位操作码可以表示16条指令但如果其中3条要扩展成8位操作码那这3条就占用了3个4位编码剩下的13个4位编码才能给短指令用。这个逻辑一定要理清楚不然很容易算错。第二个坑是地址码的寻址范围。题目说“地址空间64KB”但没说寻址方式。如果是直接寻址那地址码就是16位如果是寄存器间接寻址那地址码可能只需要4位因为寄存器数量少。所以一定要看清楚题目里的寻址方式描述。2.2 寻址方式分析题的答题框架寻址方式这类题胡老师喜欢考“给定一个指令序列分析每条指令的寻址方式”或者“比较两种寻址方式的优劣”。这类题的核心是把寻址方式和访存次数挂钩。我总结了一个答题框架基本上能覆盖90%的寻址方式题目寻址方式有效地址计算访存次数典型用途立即寻址操作数在指令中0常量赋值寄存器寻址操作数在寄存器中0变量运算直接寻址EA 地址码1全局变量访问间接寻址EA (地址码)2指针操作寄存器间接寻址EA (寄存器)1数组遍历变址寻址EA 变址寄存器 偏移1数组元素访问相对寻址EA PC 偏移1分支跳转这个表格的关键在于“访存次数”这一列。因为访存次数直接决定了指令的执行时间而执行时间又直接影响CPU性能。所以你在答题的时候一定要把“访存次数”和“性能影响”联系起来。比如“间接寻址需要两次访存比直接寻址多一次因此在性能敏感的场合应尽量避免使用”。还有一个容易忽略的点是寻址方式对指令长度的影响。立即寻址和直接寻址都需要在指令中携带操作数或地址所以指令长度会比较长而寄存器寻址只需要寄存器编号指令长度可以很短。这个取舍在RISC架构里特别明显——MIPS只保留了立即寻址、寄存器寻址、基址寻址和PC相对寻址四种就是为了保持指令长度固定。2.3 指令流水线兼容性设计题这类题通常出现在第4章之后题目会给你一个已有的指令集然后要求你“增加一条新指令使其不破坏流水线兼容性”。这类题难度较大因为需要同时考虑指令格式、流水线级数、数据通路等多个方面。我的解题思路是分三步走第一步分析新指令的操作类型。是算术运算、访存、还是控制转移不同类型对应不同的流水线阶段。比如算术指令只需要取指、译码、执行、写回四个阶段而访存指令需要额外的访存阶段。第二步检查新指令是否引入新的冒险。比如如果新指令需要两个周期才能完成那就要考虑是否会产生结构冒险或数据冒险。如果会就需要在流水线中插入气泡或者增加前递通路。第三步验证指令编码是否冲突。新指令的操作码不能和已有指令冲突如果操作码空间不够就需要扩展操作码位数但这又会影响指令长度和译码复杂度。我印象最深的是有一道题要求“增加一条同时完成加法和访存的指令”。这道题看起来简单但实际上非常棘手因为加法和访存分别属于执行阶段和访存阶段如果要在一条指令里完成要么增加流水线级数要么让这条指令占用两个周期。最后我的答案是这条指令会破坏流水线的单周期发射特性建议拆成两条指令实现。这个答案不一定标准但体现了对流水线本质的理解。3. 流水线与性能分析题的精算方法3.1 流水线加速比的精确计算与常见误区流水线加速比是课后题里出现频率最高的计算题没有之一。公式看起来很简单加速比 非流水线执行时间 / 流水线执行时间。但实际操作中至少有五个地方容易出错。第一个误区是忽略流水线建立时间。非流水线执行n条指令需要nT的时间T是单条指令执行时间。流水线执行n条指令需要(k n - 1) * t的时间k是流水线级数t是时钟周期。所以加速比 nT / ((k n - 1)*t)。如果题目说“忽略流水线建立时间”那就可以简化为k。但很多题目不会明确说忽略所以你要自己判断。第二个误区是混淆时钟周期和执行时间。流水线的时钟周期取决于最慢的那一级而不是所有级的平均值。比如五级流水线各级延迟分别是2ns、3ns、2ns、4ns、2ns那时钟周期是4ns而不是2.6ns。这个点在计算题里经常出现很多人直接取平均值结果全错。第三个误区是忘记考虑流水线冒险带来的停顿。如果题目给出了分支指令的比例和分支预测准确率那就要计算分支惩罚。比如分支指令占20%预测准确率90%那就有2%的指令会产生分支惩罚。如果分支惩罚是2个周期那平均每条指令的停顿就是0.02*20.04个周期。第四个误区是流水线级数增加带来的收益递减。很多人以为流水线级数越多加速比越高但实际上级数增加会导致时钟周期缩短的收益被流水线寄存器开销抵消。比如从5级增加到10级时钟周期可能只缩短了30%但流水线寄存器延迟增加了所以实际加速比可能只有1.5倍。第五个误区是忽略指令之间的依赖关系。如果题目给出了一段具体的指令序列那就要逐条分析数据依赖和控制依赖。比如“ADD R1, R2, R3”后面紧跟“SUB R4, R1, R5”那第二条指令就需要等待第一条指令写回R1除非有前递通路。我整理了一个流水线加速比的计算模板基本上能覆盖所有变体加速比 (非流水线CPI * 指令数 * 时钟周期_非流水线) / (流水线CPI * 指令数 * 时钟周期_流水线)其中流水线CPI 理想CPI 停顿周期数/指令数。理想CPI通常是1单发射或小于1多发射。停顿周期数包括数据冒险停顿、控制冒险停顿、结构冒险停顿。3.2 数据冒险与控制冒险的检测与解决数据冒险和控制冒险是流水线设计的核心难点也是课后题里最容易出综合题的地方。这类题通常给你一段汇编代码然后问你“这段代码在五级流水线上执行时会产生哪些冒险如何解决”。我的解题步骤是这样的第一步画出流水线时空图。把每条指令的取指、译码、执行、访存、写回五个阶段按周期画出来。这个图是后续分析的基础一定要画准确。第二步标记数据依赖。如果指令i的目的寄存器是指令j的源寄存器那指令j就依赖于指令i。依赖分为RAW写后读、WAR读后写、WAW写后写三种。在按序流水线中WAR和WAW不会产生冒险只有RAW会产生冒险。第三步计算需要停顿的周期数。如果指令j在指令i写回之前就需要读取寄存器那就需要停顿。停顿周期数 写回周期 - 需要读取的周期。比如指令i在第5周期写回指令j在第3周期需要读取那就需要停顿2个周期。第四步分析是否可以用前递解决。前递就是把执行阶段的结果直接传给下一条指令而不等待写回。如果指令i在EX阶段产生结果指令j在EX阶段需要这个结果那就可以通过前递解决不需要停顿。但如果指令i是访存指令结果在MEM阶段才产生而指令j在EX阶段就需要那就需要停顿1个周期。第五步分析控制冒险。分支指令在EX阶段才能确定是否跳转所以如果分支指令后面紧跟的指令需要根据分支结果来决定是否执行那就需要停顿。停顿周期数取决于分支指令在流水线的哪个阶段解析。如果是EX阶段解析那需要停顿2个周期假设分支指令在ID阶段译码EX阶段计算目标地址。我见过一道很经典的题给了一段包含RAW依赖和分支指令的代码要求计算在“无前递”“有前递”“有前递分支预测”三种情况下的执行周期数。这道题我做了三遍才完全搞明白关键是要把每种情况下的时空图都画出来然后逐周期数。3.3 存储层次与Cache性能计算Cache相关的计算题是另一个重灾区。这类题通常给你一个访问序列然后问你“命中率是多少”“平均访存时间是多少”“哪种替换策略更好”。计算命中率的关键是理解Cache的映射方式和替换策略。直接映射Cache的命中率计算最简单因为每个地址只能映射到一个Cache行。组相联Cache需要检查组内所有行如果组内有空行就直接放入如果没有空行就根据替换策略选择一行替换。我总结了一个Cache计算题的通用步骤第一步确定地址划分。把地址分成Tag、Index、Offset三部分。Offset位数 log2(块大小)Index位数 log2(Cache行数/组相联度)Tag位数 地址总位数 - Index位数 - Offset位数。第二步模拟访问序列。对于每个访问地址先计算Index找到对应的组然后比较Tag。如果Tag匹配且有效位为1就是命中否则就是缺失。第三步更新Cache状态。如果是缺失需要根据替换策略选择要替换的行。LRU策略需要记录每行的最近访问时间FIFO策略需要记录每行的进入时间随机策略就随便选一行。第四步计算命中率和平均访存时间。命中率 命中次数 / 总访问次数。平均访存时间 命中时间 缺失率 * 缺失代价。这里有一个容易忽略的点写操作的处理。如果题目里包含写操作那就要考虑写直达和写回两种策略。写直达每次写操作都要写内存所以写操作的缺失代价很高写回只在替换时才写内存所以写操作的缺失代价较低但需要维护脏位。还有一个进阶考点是多级Cache的包含关系。如果L1和L2是包含关系那L1的缺失会去L2查找L2的缺失会去内存查找。如果L1和L2是非包含关系那L1的缺失可能直接在L1和L2之间传输不经过内存。这个区别在计算平均访存时间时非常关键。4. 多核与并行体系结构题的解题思路4.1 缓存一致性协议题的分析方法缓存一致性是多核体系结构的核心问题也是胡老师这本书后半部分的重点。这类题通常给你一个多核系统的访问序列然后问你“在MESI协议下每个Cache行的状态如何变化”。MESI协议有四个状态Modified已修改、Exclusive独占、Shared共享、Invalid无效。状态转换的规则看起来复杂但其实可以用一个简单的口诀来记读操作会把其他核的M状态变成S状态写操作会把其他核的S状态变成I状态。我解这类题的时候会画一个表格行是访问序列列是每个核的Cache行状态。每执行一个访问就更新表格。比如访问序列Core0状态Core1状态说明Core0读AEICore0独占ACore1读ASSCore0从E变SCore1从I变SCore0写AMICore0从S变MCore1从S变ICore1读ASSCore0从M变S并写回Core1从I变S这个表格法看起来笨但非常有效因为MESI的状态转换是确定性的你只要按规则一步步推就行。关键是要记住M状态的数据是最新的E状态的数据和内存一致S状态的数据和内存一致但可能被其他核共享I状态的数据无效。还有一个容易出错的地方是写回操作。当M状态的Cache行被替换时需要先写回内存。如果题目里包含Cache替换那就要考虑写回带来的额外访存。这个点在计算平均访存时间时经常被忽略。4.2 并行编程模型与性能分析并行编程模型这类题通常出现在最后一章题目会给你一个并行算法的描述然后问你“在某种并行模型下加速比是多少”“存在哪些并行开销”。这类题的核心是Amdahl定律和Gustafson定律。Amdahl定律说的是如果程序中只有一部分可以并行化那无论增加多少处理器加速比都有一个上限。公式是加速比 1 / (S P/N)其中S是串行部分比例P是并行部分比例N是处理器数量。Gustafson定律说的是如果问题规模可以随处理器数量增加而增加那加速比可以线性增长。公式是加速比 S P*N。这两个定律看起来矛盾但其实是从不同角度描述同一个问题。Amdahl定律假设问题规模固定Gustafson定律假设问题规模可变。在实际答题时要根据题目描述判断用哪个定律。除了加速比还要考虑并行开销。并行开销包括线程创建和销毁的开销、线程间同步的开销、数据通信的开销、负载不均衡的开销。这些开销会降低实际加速比。比如如果同步开销占10%那即使并行部分占90%实际加速比也会比理论值低很多。我印象最深的是有一道题要求“分析一个矩阵乘法并行算法的性能”。这道题的关键是分块大小对性能的影响。分块太小通信开销大分块太大负载不均衡。最优分块大小是让计算时间和通信时间相等。这个结论在分布式计算和GPU编程里都非常重要。4.3 多核Cache层次设计题多核Cache层次设计是胡老师这本书的压轴内容也是课后题里最综合的一类。这类题通常给你一个多核系统的需求描述比如“4个核每个核有私有L1共享L2”然后问你“这种设计有什么优缺点”“如何改进”。这类题没有标准答案但有一个分析框架第一分析私有Cache的优缺点。私有Cache的优点是访问延迟低、带宽高因为每个核有自己的Cache不需要和其他核竞争。缺点是缓存一致性开销大因为需要维护多个Cache之间的数据一致性。第二分析共享Cache的优缺点。共享Cache的优点是缓存利用率高因为多个核可以共享数据不需要每个核都存一份。缺点是访问延迟高、带宽竞争激烈因为多个核同时访问同一个Cache。第三分析混合设计的取舍。私有L1共享L2是最常见的混合设计。私有L1保证单核性能共享L2保证多核数据共享。但L2的容量和相联度需要仔细设计容量太小会导致缺失率高相联度太低会导致冲突缺失多。第四考虑NUCA非均匀Cache访问。在大规模多核系统中L2或L3可能被分成多个Bank每个Bank的访问延迟不同。靠近核的Bank访问快远离核的Bank访问慢。NUCA设计的目标是让数据尽量放在靠近访问它的核的Bank里。我见过一道很经典的题要求“设计一个8核系统的Cache层次要求单核性能不低于某阈值多核加速比不低于某阈值”。这道题我花了整整一个下午才做完关键是要在单核性能和多核性能之间找平衡点。最后我的方案是每个核私有32KB L18个核共享4MB L2L2分成8个Bank每个Bank 512KB用哈希函数把地址映射到Bank。这个方案不一定最优但体现了对多核Cache设计核心矛盾的理解。5. 课后答案使用中的常见问题与避坑指南5.1 答案版本混乱与错误识别网上流传的胡伟武课后答案至少有十几个版本质量参差不齐。我见过最离谱的一份把流水线加速比的公式写成了“加速比 流水线级数 / 非流水线级数”完全反了。还有一份答案Cache命中率计算时把Tag比较和Index比较搞混了导致所有结果都错了。所以你在使用任何一份课后答案之前一定要先做三件事第一检查答案的完整性。一份好的答案应该覆盖所有章节的课后题而不是只覆盖前几章。如果一份答案只有前5章的题目那后面的重点章节流水线、存储层次、多核就缺失了参考价值大打折扣。第二检查答案的一致性。同一类题目的解题方法应该是一致的。如果一份答案里流水线加速比有的题用公式算有的题用时空图算那说明这份答案可能是多人拼凑的质量不可靠。第三自己验证关键计算题。对于计算题不要直接看答案先自己算一遍然后和答案对比。如果结果不一致先检查自己的计算过程如果确认自己没错那就要怀疑答案有误。我至少发现过5处答案错误都是通过自己验算发现的。5.2 概念题答不全的补救方法概念题是很多人失分的地方因为觉得“我理解了就行不用背”。但考试的时候理解不等于能写出来。我见过很多人问他“什么是流水线冒险”他能说出一大堆但让他写下来就只写了“流水线冒险就是流水线中的冲突”太简略了拿不到分。我的补救方法是把每个概念题都当成一个小作文来写。具体来说每个概念题至少包含四个部分定义用一句话给出严格定义。比如“流水线冒险是指在流水线执行过程中由于指令之间的依赖关系或资源冲突导致下一条指令无法在预定的时钟周期内执行的情况”。分类把概念分成几个子类。比如“流水线冒险分为结构冒险、数据冒险和控制冒险三类”。原因解释每个子类产生的原因。比如“结构冒险是由于硬件资源冲突数据冒险是由于指令间的数据依赖控制冒险是由于分支指令改变了程序执行顺序”。解决方法给出每个子类的解决方法。比如“结构冒险可以通过增加硬件资源解决数据冒险可以通过前递或停顿解决控制冒险可以通过分支预测或延迟槽解决”。这个四段式结构看起来死板但非常有效因为阅卷老师就是按点给分的。你把这四个部分都写全了基本上能拿到80%以上的分数。5.3 计算题步骤分怎么拿计算题是很多人头疼的地方因为一旦结果错了可能一分都拿不到。但其实计算题的评分标准是按步骤给分的即使最终结果错了只要中间步骤正确也能拿到大部分分数。所以做计算题的时候一定要把每一步都写清楚。比如计算流水线加速比不要直接写“加速比 3.2”而要写非流水线执行时间 指令数 * 时钟周期 100 * 5ns 500ns 流水线执行时间 (流水线级数 指令数 - 1) * 时钟周期 (5 100 - 1) * 1ns 104ns 加速比 500 / 104 ≈ 4.81这样即使最后一步算错了前面的步骤分也能拿到。而且写清楚步骤还有一个好处方便自己检查。如果结果看起来不对你可以从后往前逐步检查很快就能找到错误的地方。还有一个技巧是保留中间结果的单位。很多人计算的时候不带单位最后结果就容易搞错数量级。比如“500ns / 104ns 4.81”如果你写成“500 / 104 4.81”那就要想一下这个4.81是秒还是纳秒。带上单位就不会有这个困惑。5.4 如何用课后答案反推知识盲区课后答案最大的价值不是“对答案”而是“找盲区”。我每次做完一章的课后题都会把错题和不会做的题标记出来然后分析错误原因。错误原因通常有三类第一类是概念不清。比如把“写直达”和“写回”搞混了导致Cache计算题全错。这类错误的解决方法是重新看教材对应章节把概念的定义、特点、适用场景都理清楚。第二类是计算失误。比如公式记错了或者单位换算错了。这类错误的解决方法是整理一个公式表把所有常用公式都列出来每次做题前先看一遍。第三类是思路不对。比如流水线冒险题不知道要先画时空图。这类错误的解决方法是总结每类题的解题套路形成条件反射。我自己的做法是每做完一章就写一个“错题分析表”包含题目编号、错误原因、正确解法、类似题目。这个表在期末复习的时候非常有用因为你可以直接看错题不用重新做一遍所有题。6. 从课后题到实际芯片设计的思维跃迁6.1 课后题里的工程思维胡老师这本书的课后题很多都是龙芯实际设计过程中遇到的问题的简化版。比如“设计一个支持字节寻址的指令系统”这道题在龙芯的指令系统设计里就真实出现过。当时团队争论的焦点是字节寻址会增加硬件复杂度但会提高编程灵活性。最后龙芯选择了支持字节寻址因为这是软件生态的硬需求。所以做课后题的时候不要只想着“怎么算出正确答案”而要想“如果我是芯片设计师我会怎么选”。这个思维转变很重要因为实际工程中没有标准答案只有取舍。比如流水线级数的选择课后题可能只问你“5级流水线和10级流水线的加速比分别是多少”。但实际设计中你还要考虑功耗预算、芯片面积、设计复杂度、验证难度、软件兼容性。5级流水线可能加速比低一点但功耗和面积更优10级流水线加速比高但功耗和面积可能翻倍。这个取舍在课后题里是看不到的但恰恰是实际设计中最关键的部分。6.2 性能分析的实际应用课后题里的性能分析通常只考虑CPU内部的执行时间。但实际系统的性能分析要复杂得多因为还要考虑内存带宽、I/O延迟、操作系统开销、编译器优化等因素。我举一个实际例子。假设你在设计一个嵌入式系统CPU的流水线加速比是4.8看起来很快。但如果内存带宽只有100MB/s而CPU需要200MB/s的数据那CPU就会经常停顿实际性能可能只有理论值的50%。这个瓶颈在课后题里是看不到的但实际设计中必须考虑。所以我的建议是做课后题的时候多问一句“这个结论在实际系统中成立吗”。比如Cache命中率计算题课后题通常假设访问序列是固定的。但实际程序中访问序列取决于输入数据、编译器优化、操作系统调度是动态变化的。所以实际Cache命中率往往比理论值低。6.3 从答案到能力的转化路径最后我想说的是课后答案只是工具不是目的。你真正要获得的能力是独立分析问题、设计解决方案、验证方案正确性的能力。这个能力在课后题里可以训练但需要正确的方法。我的方法是先自己做再看答案最后重做。第一遍做的时候不要看答案哪怕做不出来也要硬着头皮想。第二遍看答案的时候不要只看结果要看解题思路和步骤。第三遍重做的时候要假装自己没看过答案从头到尾独立完成。这个过程很痛苦尤其是第一遍做不出来的时候很容易想放弃。但坚持下来效果非常明显。我后来在做实际项目的时候遇到类似的性能分析问题脑子里能直接调出这些题目的解题框架根本不需要重新推导。还有一个技巧是把课后题讲给别人听。如果你能把一道题的解题思路讲清楚让一个没学过这门课的人也能听懂那说明你真正理解了。我当年就是靠这个方法把流水线和Cache的题目彻底搞明白了。讲的过程中你会发现很多自己以为懂了但其实没懂的地方这些地方就是你的知识盲区。我个人在实际操作中的体会是胡老师这本书的课后题做一遍远远不够至少要做三遍。第一遍是熟悉题型第二遍是理解原理第三遍是形成条件反射。三遍之后你不仅能在考试中拿到高分更重要的是你真正具备了体系结构设计师的思维方式。这个思维方式在你以后做任何性能优化、系统设计、甚至职业选择的时候都会派上用场。
返回列表