Files
Inbox/小技术/跨缓存行(Cache Line Split).md
2025-12-11 07:24:36 +08:00

79 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
tags:
aliases:
- 1. 宏观原理图:箱子与积木的错位
date created: 星期一, 十一月 24日 2025, 5:50:26 下午
date modified: 星期一, 十一月 24日 2025, 5:50:35 下午
---
# 1. 宏观原理图:箱子与积木的错位
想象 CPU 是一个强迫症收纳师,他手里有一排固定的收纳盒(缓存行),每个盒子长度固定是 64。
我们要存的数据(点迹) 是长度为 48 的积木条。
请看下面的图,展示了当我们把积木一条接一条紧挨着放进去时,发生了什么:
```mermaid
---
config:
theme: base
flowchart:
curve: linear
---
graph LR
%% 样式定义
classDef box fill:#e6f7ff,stroke:#1890ff,stroke-width:2px,stroke-dasharray: 5 5
classDef block1 fill:#ffccc7,stroke:#f5222d,stroke-width:2px
classDef block2 fill:#d9f7be,stroke:#52c41a,stroke-width:2px
subgraph Memory["内存空间 (连续摆放)"]
direction LR
subgraph Box1["收纳盒 1 (容量 64)"]
direction LR
A1["积木A (48)"]:::block1
B1["积木B 的头 (16)"]:::block2
end
subgraph Box2["收纳盒 2 (容量 64)"]
direction LR
B2["积木B 的身子 (32)"]:::block2
C1["…"]:::white
end
end
%% 解释连接
A1 -- 紧挨着 --> B1
B1 -- "⚠️ 惨遭腰斩 ⚠️" --> B2
```
# 2. 细节文字表述:为什么这很糟糕?
**场景还原:**
1. **强迫症规则**CPU 每次读取数据,必须**连盒带盖**端走整整一个“收纳盒”64 字节),不能只捏走里面的某一块。
2. **读取积木 A红色**
- CPU 伸手端走 **收纳盒 1**
- 积木 A 完整地在盒子里。
- **耗时**1 次搬运。**(快)**
3. **读取积木 B绿色**
- CPU 端走 **收纳盒 1**,拿到了积木 B 的**头**。
- CPU 发现身子没了,只能再去端走 **收纳盒 2**,拿到积木 B 的**身子**。
- 然后 CPU 还得在手里把这两段拼起来。
- **耗时**2 次搬运 + 拼接时间。**(慢!)**
# 3. 结论与解决方案
- **问题核心**因为数据的尺寸48不能被盒子的尺寸64整除导致后续的数据像“跨栏”一样骑在两个盒子的边界上。这叫**跨缓存行Cache Line Split**。
- **我们的方案(填充 Padding**
- 既然 48 放不进 64 很尴尬,我们就在每个积木后面**硬塞 16 块没用的泡沫Padding**。
- 把积木强行撑大到 **64**
- **结果**虽然浪费了空间但现在每个盒子正好放一个积木。CPU 拿任何积木都只需要搬 **1 次**盒子。
这就是我们为了极致性能所做的妥协:**用空间换时间**。