Skip to content

计算机体系与性能 共70题

说明:

  • 高频方向:CPU Cache、局部性、cache line、cache miss、内存对齐、大小端、流水线、分支预测、SIMD、false sharing、AoS/SoA、内存池、性能分析。

一、单选题

1. CPU Cache 的主要作用是?

A. 缓解 CPU 与内存速度差距
B. 替代所有内存
C. 保存网络连接
D. 压缩纹理

答案:A

解析:Cache 位于 CPU 和主存之间,用更快的小容量存储缓存近期访问数据。


2. 程序顺序访问数组通常性能较好的主要原因是?

A. 空间局部性好,缓存命中率高
B. 数组不占内存
C. CPU 不需要执行指令
D. 编译器会删除循环

答案:A

解析:连续内存访问更容易命中同一缓存行,也利于硬件预取。


3. 时间局部性指的是?

A. 近期访问过的数据很可能再次被访问
B. 相邻地址容易被访问
C. 时间越长数据越快
D. 线程越多越快

答案:A

解析:时间局部性强调同一数据的重复访问。


4. 空间局部性指的是?

A. 访问某地址后,附近地址也可能被访问
B. 同一数据会被重复访问
C. 所有数据都在寄存器
D. 磁盘比内存快

答案:A

解析:数组遍历常利用空间局部性。


5. Cache line 通常指?

A. Cache 与内存交换数据的基本块
B. 一行 C++ 代码
C. 网络包头
D. 屏幕扫描线

答案:A

解析:CPU 缓存按缓存行加载数据,常见大小如 64 字节。


6. cache miss 会导致?

A. CPU 等待更慢层级缓存或内存
B. 程序一定崩溃
C. 网络断开
D. 显卡重启

答案:A

解析:miss 会增加访存延迟,可能成为性能瓶颈。

cache miss 流程图


7. 以下哪种数据结构通常更 cache-friendly?

A. 连续数组
B. 随机分布链表
C. 大量指针跳转树
D. 碎片化对象链

答案:A

解析:连续数组有更好的空间局部性和预取效果。


8. 结构体内存对齐的主要目的之一是?

A. 满足硬件访问要求并提升访问效率
B. 让代码行数更少
C. 避免网络丢包
D. 替代虚函数

答案:A

解析:对齐可减少非对齐访问开销,某些平台还要求特定对齐。


9. 结构体 padding 指的是?

A. 编译器为满足对齐插入的填充字节
B. 网络填充包
C. 纹理压缩块
D. 栈溢出

答案:A

解析:成员之间或尾部可能插入 padding,影响 sizeof。


10. 大小端 endian 描述的是?

A. 多字节数据在内存中的字节顺序
B. CPU 核心数量
C. 网络延迟
D. 显卡纹理格式

答案:A

解析:小端低有效字节在低地址,大端高有效字节在低地址。


11. x86/x64 常见字节序是?

A. 小端
B. 大端
C. 随机端
D. 网络端

答案:A

解析:主流 x86/x64 平台通常为 little-endian。


12. 网络字节序通常是?

A. 大端
B. 小端
C. 随机端
D. 和显卡一致

答案:A

解析:网络协议通常使用 big-endian,又称 network byte order。


13. CPU 流水线的目的主要是?

A. 提高指令吞吐率
B. 让单条指令完全不耗时
C. 替代内存
D. 保证不发生分支

答案:A

解析:流水线让多条指令不同阶段重叠执行。


14. 分支预测失败通常会导致?

A. 流水线冲刷,性能下降
B. 内存容量增加
C. 网络包变大
D. 代码无法编译

答案:A

解析:预测失败需要丢弃错误路径上的流水线结果。


15. SIMD 的含义更接近?

A. 单指令多数据
B. 单数据多指令
C. 网络多播
D. 磁盘阵列

答案:A

解析:SIMD 可用一条指令处理多个数据元素,适合向量/矩阵/批量计算。


16. false sharing 指的是?

A. 多个线程修改同一缓存行中的不同变量导致缓存一致性抖动
B. 变量名相同
C. 共享指针为空
D. 两个文件同名

答案:A

解析:虽然变量不同,但在同一 cache line 上,跨核写入会互相使缓存失效。


17. 多线程程序中频繁写同一缓存行可能导致?

A. 缓存一致性流量增加
B. GPU 纹理变清晰
C. 磁盘更快
D. 网络更稳定

答案:A

解析:跨核心缓存行所有权来回迁移会降低性能。


18. 内存带宽瓶颈通常表示?

A. CPU/GPU 等待数据搬运,计算单元未充分利用
B. 代码没有函数
C. 网络端口不足
D. 硬盘没有分区

答案:A

解析:大量数据读写可能受限于内存带宽,而非计算能力。


19. AoS 指的是?

A. Array of Structures
B. Always on Server
C. Area of Shader
D. Async over Socket

答案:A

解析:AoS 是结构体数组,如 vector<Player>


20. SoA 指的是?

A. Structure of Arrays
B. Socket over API
C. Shader of Alpha
D. Stack of Args

答案:A

解析:SoA 把字段拆成多个数组,有利于批量访问某一字段。


21. 在只批量更新位置 x 坐标时,SoA 相比 AoS 的潜在优势是?

A. 更少无关字段被加载进缓存
B. 一定减少代码量
C. 完全不占内存
D. 禁止 SIMD

答案:A

解析:SoA 能只访问需要的字段,提升缓存利用率和向量化机会。


22. 性能分析中,FPS 下降但 CPU/GPU 都不满,可能还要关注?

A. 同步等待、锁、I/O、内存带宽、调度抖动
B. 只看代码行数
C. 只看文件名
D. 只看显示器品牌

答案:A

解析:瓶颈可能来自等待和数据搬运,而非纯计算占满。


23. prefetch 预取的目的是什么?

A. 提前把可能访问的数据加载到缓存
B. 提前关闭程序
C. 提前发送网络 ACK
D. 提前删除纹理

答案:A

解析:合理预取可隐藏部分内存延迟,但错误预取也会污染缓存。


24. 循环展开 loop unrolling 的潜在收益是?

A. 减少循环控制开销并暴露更多优化机会
B. 保证代码更短
C. 消除所有 cache miss
D. 自动修复 bug

答案:A

解析:循环展开可能提升指令级并行,但会增加代码体积。


25. 循环分块 tiling 常用于?

A. 提升缓存复用
B. 减少源文件数量
C. 改变网络协议
D. 禁用多线程

答案:A

解析:矩阵计算等场景通过分块让数据在 cache 中复用。


26. 内存池的主要性能收益是?

A. 减少频繁小对象分配释放开销和碎片
B. 提升网络带宽
C. 增加 CPU 核数
D. 自动压缩图片

答案:A

解析:游戏对象、消息包、粒子等高频对象常用池化。


27. 对象池如果复用对象时不重置状态,最可能导致?

A. 脏状态 bug
B. CPU 不能启动
C. 编译器崩溃
D. 网络协议改变

答案:A

解析:复用前必须清理状态,否则上一次使用的数据会泄漏到新逻辑。


28. 判断机器大小端时,常用方法是?

A. 写入多字节整数并查看最低地址字节
B. ping 本机
C. 读取显卡型号
D. 比较文件大小

答案:A

解析:例如 int x=1,查看首字节是否为 1。


29. volatile 在 C/C++ 中主要表示?

A. 对象可能被编译器无法感知的方式修改,限制优化
B. 保证线程同步
C. 保证原子性
D. 保证 cache 一致性

答案:A

解析:volatile 不是线程同步工具,不能替代 atomic/mutex。


30. 原子操作 atomic 的性能通常比普通变量访问?

A. 更高开销,尤其涉及跨核同步时
B. 一定更低开销
C. 完全一样
D. 不会生成机器指令

答案:A

解析:atomic 可能带来内存序和缓存一致性成本。


二、不定项选择题

1. 哪些做法通常有利于提高 cache 命中率?

A. 使用连续内存
B. 减少随机指针跳转
C. 按访问顺序组织数据
D. 频繁遍历链表随机节点

答案:A、B、C

解析:连续访问和减少指针跳转通常更 cache-friendly。


2. 哪些现象可能说明存在 cache miss 问题?

A. CPU 等待内存
B. 性能随数据规模增大突然下降
C. 链表随机访问慢
D. 顺序数组遍历很快

答案:A、B、C

解析:顺序数组快通常是利用了缓存。


3. 影响结构体 sizeof 的因素包括?

A. 成员大小
B. 成员顺序
C. 对齐规则
D. padding

答案:A、B、C、D

解析:结构体大小由成员和对齐共同决定。


4. 关于大小端,正确的是?

A. 小端低有效字节在低地址
B. 大端高有效字节在低地址
C. 网络字节序通常是大端
D. 大小端会影响多字节数据序列化

答案:A、B、C、D

解析:跨平台通信和文件格式需要明确字节序。


5. 可能导致 false sharing 的情况有?

A. 多个线程频繁写相邻变量
B. 变量位于同一 cache line
C. 跨核心缓存一致性反复失效
D. 每个线程只读常量

答案:A、B、C

解析:只读常量一般不会导致 false sharing。


6. 性能优化前应该做什么?

A. 测量和定位瓶颈
B. 建立基准数据
C. 确认 CPU/GPU/内存/I/O 谁是瓶颈
D. 凭感觉重写全部代码

答案:A、B、C

解析:先 profile 再优化,避免无效改动。


7. 游戏客户端 CPU 性能问题可能来自?

A. 脚本层和原生层频繁交互
B. 过多小对象分配
C. 锁竞争
D. 缓存不友好的数据布局

答案:A、B、C、D

解析:这些都是游戏客户端常见 CPU 问题来源。


8. 能提升数据局部性的方式包括?

A. 对象数组连续存储
B. SoA 数据布局
C. 按系统批量处理组件
D. 每帧随机访问大量散落对象

答案:A、B、C

解析:随机散落访问通常破坏局部性。


9. SIMD 适合哪些场景?

A. 批量向量计算
B. 矩阵运算
C. 粒子更新
D. 每个元素分支完全不同且不可预测

答案:A、B、C

解析:SIMD 适合相同操作作用于多份数据。


10. 分支预测更容易失败的场景包括?

A. 条件结果随机
B. 数据分布不可预测
C. 循环内大量不规则分支
D. 固定模式分支

答案:A、B、C

解析:固定模式分支更容易预测。


三、判断题

1. Cache 容量越大,访问延迟通常越低。

答案:错

解析:更大层级 cache 通常容量更大但延迟更高。


2. 顺序遍历数组通常比随机访问链表更容易利用缓存。

答案:对

解析:数组连续,链表节点可能散落。


3. 结构体成员顺序可能影响 sizeof。

答案:对

解析:调整成员顺序可能减少 padding。


4. volatile 可以替代 mutex 保证线程安全。

答案:错

解析:volatile 不提供互斥和原子性。


5. false sharing 中,不同线程访问的变量可以是不同变量。

答案:对

解析:关键是它们位于同一 cache line 且被频繁写。


6. 网络字节序通常是小端。

答案:错

解析:网络字节序通常是大端。


7. SIMD 可以让一条指令处理多个数据元素。

答案:对

解析:这是 single instruction multiple data。


8. 性能优化应该先测量再改代码。

答案:对

解析:没有 profile 容易优化错方向。


9. 内存池可以减少频繁分配释放的开销。

答案:对

解析:池化常用于高频小对象。


10. 分支预测失败不会影响流水线。

答案:错

解析:预测失败可能导致流水线冲刷。


四、填空题

1. Cache 利用的两个经典局部性是时间局部性和 ______ 局部性。

答案:空间

解析:空间局部性指附近地址可能很快被访问。


2. CPU 与内存之间交换数据的基本缓存块通常称为 cache ______。

答案:line

解析:缓存行是 cache 加载/失效的基本粒度。


3. 小端机器中,低有效字节存放在 ______ 地址。

答案:低

解析:little-endian:低字节低地址。


4. 网络字节序通常采用 ______ 端。

答案:大

解析:big-endian 是网络协议常见字节序。


5. SIMD 的中文含义可写作:单指令 ______ 数据。

答案:多

解析:single instruction multiple data。


6. 多个线程写同一 cache line 上不同变量造成的性能问题称为 ______ sharing。

答案:false

解析:false sharing 会造成缓存一致性抖动。


7. 结构体为满足对齐规则插入的无效字节称为 ______。

答案:padding

解析:padding 会影响结构体大小。


8. SoA 的全称是 Structure of ______。

答案:Arrays

解析:SoA 将字段拆成数组。


9. AoS 的全称是 Array of ______。

答案:Structures

解析:AoS 是结构体数组。


10. 性能分析工具中,cache-misses 常用于观察 ______ 未命中情况。

答案:缓存

解析:cache miss 指缓存未命中。


五、简答题

1. 解释时间局部性和空间局部性。

参考答案:时间局部性指刚访问过的数据很可能再次被访问,例如循环中反复使用同一变量;空间局部性指访问某地址后,附近地址也很可能被访问,例如顺序遍历数组。CPU Cache 和预取机制都依赖局部性提升性能。


2. 什么是 cache miss?为什么会影响游戏性能?

参考答案:cache miss 是 CPU 访问数据时未在当前缓存层级命中,需要访问更慢的下级缓存或内存。游戏每帧时间很短,大量随机访问、指针跳转或数据布局差会导致 CPU 等待内存,表现为帧耗时上升、卡顿。


3. 解释 false sharing。

参考答案:false sharing 指多个线程修改不同变量,但这些变量位于同一 cache line。由于缓存一致性协议以 cache line 为单位维护所有权,多个核心写入会让该缓存行在核心间反复失效和迁移,导致性能下降。


4. AoS 和 SoA 有什么区别?

参考答案:AoS 是结构体数组,适合一次处理单个对象的多个字段;SoA 是多个字段数组,适合批量处理某一类字段。游戏 ECS 和批量更新中,SoA 往往能减少无关字段加载,提高 cache 命中和 SIMD 机会。


5. 为什么结构体成员顺序会影响大小?

参考答案:编译器会根据成员对齐要求插入 padding。若小成员和大成员交错排列,可能产生更多填充。把大对齐成员集中排列,有时可以减少结构体大小,但还要考虑可读性和 ABI 约束。


6. 如何判断大小端?

参考答案:可以定义一个多字节整数如 uint32_t x = 1,再用 uint8_t* 查看最低地址字节。如果最低地址字节为 1,则为小端;如果为 0 且最高字节为 1,则为大端。


7. 游戏客户端性能优化为什么要先 profile?

参考答案:性能瓶颈可能在 CPU、GPU、内存带宽、I/O、锁等待、脚本交互等不同位置。没有数据就优化容易改错方向。profile 能确认热点函数、帧耗时、cache miss、GC/分配、锁等待和渲染瓶颈,再针对性处理。


六、场景分析题

1. 场景:游戏里有 10 万个粒子,每帧只更新 position 和 velocity,但数据结构是 struct Particle { pos; vel; color; lifetime; material; ... } 的数组。CPU 更新较慢,你会怎么优化?

参考答案:可以考虑从 AoS 改为 SoA,把 position、velocity、lifetime 等热字段拆成连续数组,更新时只加载需要字段,减少 cache line 中无关数据;批量循环处理,减少分支;尝试 SIMD;按活跃粒子紧凑排列;使用对象池避免频繁分配;profile cache miss 和循环热点,确认优化效果。


2. 场景:多线程更新玩家状态,每个线程写自己的计数器,但性能随线程数增加反而下降。请分析可能原因。

参考答案:可能是 false sharing:多个线程写的计数器相邻,位于同一 cache line,导致缓存行在核心间反复失效。解决方式包括为每个线程的数据做 cache line 对齐和 padding,使用线程本地存储,批量汇总结果,减少共享写。


3. 场景:某系统使用链表保存大量可见对象,每帧遍历做剔除,Profiler 显示 CPU 时间高。如何分析和优化?

参考答案:链表节点分散,遍历时 cache miss 多,预取效果差。可改为连续数组/vector 保存活跃对象,删除时使用 swap-remove 或延迟压缩;按空间区域分桶,减少遍历数量;热冷数据分离,只遍历剔除需要的包围盒和 transform;用 profile 对比 cache miss、遍历时间和内存占用。

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0