# 第 80 题：`torch.cuda.empty_cache()`的副作用？为什么不能频繁调用？

## 题目

`torch.cuda.empty_cache()`的副作用？为什么不能频繁调用？

---

## 完整讲解

### 一、empty_cache() 做什么

`torch.cuda.empty_cache()` 会释放 **PyTorch 的 CUDA 缓存池** 中当前未占用的块归还给 CUDA driver，**不释放** 仍被 tensor 占用的显存。目的是在「已 free 但被缓存池持有」时，让后续 alloc 能向 driver 要新块或让其他进程用到显存。

### 二、副作用

- **同步**：会与 CUDA 同步（或触发 driver 回收），可能 **stall** 当前 stream，带来一次全局同步点，影响性能与 overlap。
- **碎片**：缓存池清空后，后续分配重新从 driver 要块，**历史「大块」布局被打散**，可能反而增加碎片或分配失败（尤其在大块与小块交替分配时）。
- **不能减「在用」显存**：只还回未用缓存，不改变已分配 tensor 的占用；误以为「调了就能省显存」而频繁调用，只会增加同步与碎片风险。

### 三、何时用、为何不能频繁调

- **适合**：进程内显存已大量释放、且希望尽快把空闲还给系统（如多阶段脚本、中间换模型）时，**偶尔** 调一次。
- **不宜频繁**：训练循环内每 step 或每 N step 调一次没有意义（显存仍被占用），且会引入同步与碎片，**降低吞吐、增加 OOM 风险**。正确做法是优化模型与 batch、用 checkpoint 等减峰值，而不是依赖 empty_cache。

---

## 面试要点

- empty_cache 只释放缓存池中未用块，不释放在用 tensor；会触发同步、可能加剧碎片。
- 频繁调用无益且有害：同步 stall、碎片增加；不能当「省显存」手段。
- 仅适合阶段切换时偶尔调用，训练循环内不要用。

---

## 记忆要点

1. 只还缓存池空闲块，不释放在用显存；会同步、可能加重碎片。
2. 训练循环里不要频繁调；用 checkpoint/batch 优化代替。
3. 仅阶段切换、希望还显存给系统时偶尔用。

[返回模块](./README.md) | [返回总览](../README.md)
