Files
Inbox/小技术/跨缓存行(Cache Line Split).md

79 lines
2.8 KiB
Markdown
Raw Permalink Normal View History

2025-12-11 07:24:36 +08:00
---
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 次**盒子。
这就是我们为了极致性能所做的妥协:**用空间换时间**。