Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

系统与高性能 / Systems & Performance

系统与高性能知识体系

操作系统 / Operating Systems

OS 底层知识学习路线 / A Learning Path for Operating System Internals

存储硬件基础 — 磁盘到底怎么存数据 / Storage Hardware Fundamentals: How Disks Store Data

BIOS vs UEFI — 固件的本质 / BIOS and UEFI: Understanding Firmware

磁盘分区表 — GPT 与 MBR / Disk Partition Tables: GPT and MBR

文件系统核心概念 — inode、journal、COW / Filesystem Concepts: Inodes, Journaling, and Copy-on-Write

常见文件系统格式详解 — FAT 到 ZFS 的进化史 / Filesystem Formats from FAT to ZFS

Linux 启动全流程 — 从通电到登录提示符 / The Linux Boot Process from Power-On to Login

Windows 启动全流程 — 与 Linux 的对比视角 / The Windows Boot Process in Comparison with Linux

Linux 文件系统层次结构 (FHS) — 目录树的哲学 / The Linux Filesystem Hierarchy Standard

Linux 挂载机制 — mount、VFS 与 fstab / Linux Mounting with Mount, VFS, and Fstab

Linux 磁盘管理实战 — 从分区到挂载全流程 / Practical Linux Disk Management from Partitioning to Mounting

Windows 磁盘与文件系统 — 盘符帝国的秩序 / Windows Disks and Filesystems

ext4 深入 — 从超级块到 Extent Tree / Ext4 in Depth from Superblocks to Extent Trees

btrfs 深入 — B-tree 是万能的 / Btrfs in Depth and Its B-Tree Architecture

双系统 — EFI 分区共存与 GRUB chainload / Dual Boot with Shared EFI Partitions and GRUB Chainloading

计算系统 / Computing Systems

计算系统:计算机如何执行与加速程序

从 C++ 源码到 CPU 执行

CPU 流水线、乱序执行与分支预测

Cache、一致性、伪共享与 NUMA

GPU、SM、Warp 与显存

计算执行模型:程序怎样映射到机器

SIMD 与编译器向量化

C++ 多线程与 OpenMP

CUDA 平台与编程模型

CUDA Kernel、内存与性能

CPU-GPU 异构流水线

MPI 与分布式并行

并行算法模式

性能模型与工具

递进学习项目:从单线程到集群

历史完整正文 / Original Deep Dives

历史完整正文:统一前文章逐篇保留

原体系结构与硬件 / Original Architecture

硬件编程与高性能计算:一张可走通的学习地图 / A Practical Learning Map for Hardware Programming and HPC

计算机体系结构:CPU、内存与 GPU / Computer Architecture: CPUs, Memory, and GPUs

计算机架构基础——为什么 GPU 比 CPU 更快 / Computer Architecture Fundamentals: Why GPUs Outperform CPUs

并行计算理论——30 天训练能优化到多快? / Parallel Computing Theory and the Limits of Training Acceleration

GPU 架构深入——上万个核心如何分工协作 / GPU Architecture and Massive Parallel Execution

CUDA 编程模型——把矩阵乘法映射到 GPU / The CUDA Programming Model for Mapping Matrix Multiplication to GPUs

CUDA 内存管理——百亿参数如何装进显存 / CUDA Memory Management for Large Models

CUDA 性能优化——从 30 天缩短到 10 天 / CUDA Performance Optimization

CPU 并行编程——OpenMP 与 SIMD 向量化 / CPU Parallel Programming with OpenMP and SIMD

HPC 集群与 MPI——多节点分布式训练 / HPC Clusters and MPI for Distributed Training

异构计算——CPU 与 GPU 如何协同工作 / Heterogeneous Computing with CPUs and GPUs

深度学习训练优化实战——从 30 天到 3 天 / Deep Learning Training Optimization from Thirty Days to Three

性能分析工具——找到真正的瓶颈 / Performance Analysis Tools for Finding Real Bottlenecks

NPU 全景——昇腾/寒武纪/TPU/苹果生态 / The NPU Landscape: Ascend, Cambricon, TPU, and Apple

未来趋势——2030 年的计算机会是什么形态 / Future Computing Trends Toward 2030

硬件与高性能计算:从“程序为什么慢”开始 / Hardware and HPC Starting from Why Programs Are Slow

原并行计算 / Original Parallel Computing

并行计算:从 SIMD 到 MPI / Parallel Computing from SIMD to MPI

并行计算全景:从晶体管、CPU、GPU 到计算集群 / Parallel Computing from Transistors, CPUs, and GPUs to Clusters

并行计算基础:任务分解、加速比与可扩展性 / Parallel Computing Fundamentals: Decomposition, Speedup, and Scalability

处理器体系结构:从指令流水线到多核芯片 / Processor Architecture from Instruction Pipelines to Multicore Chips

CPU 并行:多线程、SIMD、Cache 一致性与 NUMA / CPU Parallelism with Threads, SIMD, Cache Coherence, and NUMA

内存层次:Cache、带宽、局部性与一致性 / Memory Hierarchies, Bandwidth, Locality, and Coherence

GPU 体系结构:SIMT、Warp、SM 与吞吐优先设计 / GPU Architecture with SIMT, Warps, and Streaming Multiprocessors

CUDA 编程模型:Thread、Block、Grid 与内存协作 / CUDA Threads, Blocks, Grids, and Cooperative Memory Access

并行算法模式:Map、Reduce、Scan、Stencil 与任务图 / Parallel Patterns: Map, Reduce, Scan, Stencil, and Task Graphs

异构计算:CPU、GPU、NPU 如何协同工作 / Heterogeneous Computing with CPUs, GPUs, and NPUs

分布式并行:MPI、集合通信、RDMA 与多机多卡 / Distributed Parallelism with MPI, Collective Communication, and RDMA

性能工程:测量、Roofline、瓶颈定位与优化闭环 / Performance Engineering with Measurement, Roofline, and Bottleneck Analysis

并行计算实战:AI、CAE、图像与科学计算 / Parallel Computing for AI, CAE, Imaging, and Scientific Computing

并行计算实践路线:从单核优化到多机多卡 / A Parallel Computing Project Path from Single-Core to Multi-Node GPUs

性能工程 / Performance Engineering

性能工程全景:从现象到证据 / Performance Engineering Overview

基准测试:把变快变成可信实验 / Benchmarking as Evidence

系统级追踪:用时间线看等待、调度与 I/O / System Tracing

CPU、内存、Cache 与 NUMA:把热点解释到硬件行为 / CPU, Memory, Cache and NUMA

GPU、Roofline 与异构瓶颈 / GPU, Roofline and Heterogeneous Bottlenecks

优化闭环:从假设、改动到回归守护 / Optimization, Regression and Production

xv6 源码学习 / xv6 Source Learning

xv6 源码学习专题 / xv6 Source Learning

xv6 学习路线:从 C 指针到操作系统源码 / xv6 Learning Roadmap

读 xv6 必备的 C 语言和指针基础 / C And Pointers For xv6

读 xv6 必备的 RISC-V 基础 / RISC-V Basics For xv6

如何阅读 xv6 源码 / How To Read xv6 Source

xv6 启动与内核入口 / xv6 Boot And Kernel Entry

xv6 内存布局与页表 / xv6 Memory Layout And Page Tables

xv6 trap、中断与系统调用 / xv6 Traps Interrupts And System Calls

xv6 进程与 struct proc / xv6 Process And struct proc

xv6 上下文切换与调度器 / xv6 Context Switch And Scheduler

xv6 sleep/wakeup、wait 与 exit / xv6 Sleep Wakeup Wait And Exit

xv6 锁与并发 / xv6 Locks And Concurrency

xv6 文件描述符与 inode / xv6 File Descriptor And Inode

xv6 文件系统与日志 / xv6 File System And Log

xv6 设备驱动、console、UART 与磁盘 / xv6 Device Driver Console UART And Disk

xv6 用户程序与 shell / xv6 User Programs And Shell

用 QEMU/GDB 调试 xv6 / Debugging xv6 With QEMU And GDB

从 xv6 过渡到 Linux 0.11 / Bridge From xv6 To Linux 0.11

xv6 专题总结与实践项目 / xv6 Summary And Practice Projects

本页目录

系统与高性能知识体系 ​

这个大区回答三个连续问题:操作系统怎样管理资源,计算机怎样执行程序,以及怎样用测量证据改进性能。

应用看到的是线程、文件、地址和函数调用,硬件执行的却是指令、缓存访问、中断和设备传输。系统学习的目的,就是建立这两层之间的因果链。当程序变慢、崩溃或扩展性下降时,能够从现象追到调度、虚拟内存、Cache、NUMA、I/O 或通信,而不是只凭经验调整参数。

text
操作系统
  ├─ 进程、线程、调度
  ├─ 虚拟内存、文件和 I/O
  └─ 启动、磁盘与存储
          |
          v
计算系统
  ├─ 体系结构:CPU/GPU 怎样执行
  ├─ 执行模型:串行、SIMD、线程、SIMT、进程
  └─ 并行计算:OpenMP、CUDA、MPI 与并行模式
          |
          v
性能工程
  └─ Benchmark、Profiling、Roofline 与回归验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14

1. 程序从源码到执行 ​

源代码首先经过预处理、编译、汇编和链接,形成可执行文件与动态库。

text
Source
  -> compiler front end
  -> optimizer
  -> object files
  -> linker
  -> executable / shared libraries
  -> loader
  -> process address space
1
2
3
4
5
6
7
8

编译器把语言语义转换为目标指令。 优化会内联、消除无用代码、重排循环和进行向量化,但必须保持可观察行为。

链接器解析符号、合并 Section 并生成重定位信息。 装载器映射可执行文件和动态库,建立进程初始地址空间。

启动慢可能来自:

  • 动态库数量和重定位;
  • 磁盘与页面缺失;
  • 全局构造;
  • 配置和资源扫描;
  • 字体、图形和 GPU 初始化;
  • 网络和许可证连接;
  • JIT 或 Shader 编译。

把启动看成完整时间线,才能定位真实阶段。

2. 进程与线程 ​

进程提供资源和地址空间边界。 线程共享进程内存,但拥有独立栈、寄存器和调度状态。

text
Process
├─ virtual address space
├─ file descriptors / handles
├─ security context
├─ Thread A: stack + registers
├─ Thread B: stack + registers
└─ shared heap and mappings
1
2
3
4
5
6
7

线程切换需要保存与恢复执行状态。 过多线程会增加调度、栈内存、Cache 抖动和同步成本。

进程隔离比线程强。 崩溃、依赖冲突和权限风险较高的模块适合进程外执行。

IPC 可以使用管道、Socket、共享内存和消息协议。 共享内存速度高,但同步与生命周期更加复杂。

3. 调度 ​

操作系统调度器在可运行线程之间分配 CPU 时间。

线程状态大致包括:

  • Running;
  • Runnable;
  • Sleeping;
  • Waiting for I/O;
  • Waiting for lock;
  • Stopped。

CPU 利用率低时,要区分线程不可运行还是没有足够工作。 Runnable 很多而 Running 受限,说明 CPU 或配额饱和。

优先级不能替代容量设计。 错误使用高优先级可能饿死其他工作,并增加系统尾延迟。

线程亲和性适合稳定、拓扑敏感的计算任务。 交互和混合负载中,过度绑核可能限制调度器优化。

4. 虚拟内存 ​

每个进程看到连续虚拟地址,页表把它映射到物理页或其他后端。

text
Virtual Address
  -> page table walk
  -> physical page
  -> DRAM / mapped file / device
1
2
3
4

TLB 缓存地址转换。 工作集很大或访问随机时,TLB miss 会增加页表遍历。

缺页分为不同类型。 匿名页首次访问、文件映射尚未驻留和真正磁盘换入的成本差异很大。

RSS、虚拟地址空间和提交量不是同一指标。 分析内存问题要区分可达对象、映射、共享页、页缓存和交换。

5. Cache 与内存层次 ​

处理器访问寄存器和 Cache 比访问主存快得多。

text
Registers
  -> L1
  -> L2
  -> LLC
  -> Local DRAM
  -> Remote NUMA DRAM
  -> Storage / Network
1
2
3
4
5
6
7

连续访问有利于 Cache Line 利用和硬件预取。 链式随机访问更容易受延迟限制。

时间局部性描述数据很快再次使用。 空间局部性描述相邻地址很快被访问。

数据布局会影响向量化、工作集和带宽。 AoS 与 SoA 没有绝对优劣,要看算法每次需要哪些字段。

6. 文件与 I/O ​

文件 API 背后可能经过页缓存、文件系统、块层、驱动和设备。

text
read / write
  -> page cache
  -> filesystem
  -> block layer
  -> device queue
  -> storage device
1
2
3
4
5
6

一次读取很快可能因为数据已经在页缓存。 一次写入返回也不一定代表数据已经持久化到介质。

可靠保存通常需要临时文件、Flush、同步和原子替换。 具体保证取决于操作系统和文件系统协议。

顺序大块 I/O 与随机小 I/O 的性能特征不同。 Benchmark 必须模拟真实访问模式。

7. CPU 执行 ​

现代 CPU 通过流水线、乱序执行、分支预测和多级 Cache 降低单线程延迟。

前端负责取指、预测和译码。 后端把微操作调度到整数、浮点、向量和访存执行单元。

依赖链会限制指令级并行。 分支预测错误会丢弃错误路径上的工作。

IPC 是每周期退休指令数,但它不是跨工作负载通用性能指标。 相同任务完成时间和正确性才是最终结果。

SIMD 让一条指令处理多个元素。 连续数据、简单控制流和明确别名有利于自动向量化。

8. GPU 与异构系统 ​

GPU 用大量线程和高带宽处理规则数据并行。 它更关注吞吐,而不是单个线程的最低延迟。

GPU 性能受到:

  • 并行规模;
  • Warp 发散;
  • 内存访问合并;
  • 寄存器与共享内存;
  • Host/Device 传输;
  • Kernel 启动与同步;
  • 多 Stream 并发;
  • 功耗和热限制。

CPU 与 GPU 应按任务特征分工。 不规则控制、操作系统服务和小任务通常留在 CPU,规则大规模 Kernel 交给 GPU。

端到端时间必须包含数据准备、传输和结果提交。

9. 网络路径 ​

网络请求跨越应用、Socket、协议栈、网卡、交换设备和远端服务。

text
application buffer
  -> socket
  -> TCP / UDP / QUIC
  -> kernel queues
  -> NIC
  -> network
  -> remote stack and application
1
2
3
4
5
6
7

延迟由传播、排队、处理、重传和应用等待共同组成。 带宽高不代表小消息延迟低。

TCP 提供有序可靠字节流,但应用仍需定义消息边界、超时和取消。 UDP 保留数据报边界,却把可靠性和顺序选择交给应用或上层协议。

10. 并发正确性 ​

共享可变状态需要同步。 数据竞争、死锁、活锁和饥饿是不同问题。

锁建立互斥与内存可见性,但临界区过大会降低扩展性。 原子操作只保护对应对象,不自动保护复合不变量。

优先减少共享,再选择同步方式。 不可变快照、消息传递和线程局部状态经常比复杂无锁结构更可靠。

11. 性能工程闭环 ​

text
define goal
  -> fix workload
  -> establish baseline
  -> collect evidence
  -> form falsifiable hypothesis
  -> make minimal change
  -> verify correctness and performance
  -> guard regression
1
2
3
4
5
6
7
8

工具选择取决于问题层次。

  • 火焰图观察 CPU 调用路径;
  • 时间线观察线程、I/O 和设备关系;
  • 计数器解释 Cache、分支和带宽;
  • Trace 连接分布式请求;
  • Benchmark 验证改动是否可复现。

只看单个利用率指标不能证明瓶颈。

12. 可靠性与恢复 ​

系统能力还包括失败后的行为。

需要考虑:

  • 进程崩溃;
  • 磁盘写满;
  • 网络分区;
  • 依赖超时;
  • 任务取消;
  • 机器重启;
  • Checkpoint 损坏;
  • 版本回滚;
  • 资源泄漏。

错误应停在接近根因的边界,并携带足够上下文。 静默重试可能放大负载并隐藏真实故障。

13. 学习与实验方法 ​

每个机制都应通过小实验验证:

  1. 改变数组步长观察 Cache 拐点;
  2. 改变线程数绘制扩展曲线;
  3. 比较串行、SIMD 和多线程;
  4. 区分冷缓存与热缓存 I/O;
  5. 固定亲和性观察 NUMA;
  6. 分离 GPU 传输与 Kernel;
  7. 注入锁竞争和网络延迟;
  8. 保存环境与原始样本。

实验目标是建立可证伪理解,而不是得到一个漂亮数字。

每次结论都应能指出对应的测量命令、输入数据和适用硬件范围。

权威入口 ​

  1. 操作系统
  2. 计算系统:体系结构、执行模型与并行计算
  3. 性能工程

原来的并行计算目录保留旧链接兼容,但不再维护第二套权威正文。

一条程序实际经历了什么 ​

text
源代码
  │ 编译、链接与装载
  v
进程虚拟地址空间
  │ 调度到某个逻辑处理器
  v
指令流水线 <-> Cache / 主存 <-> NUMA 或设备内存
  │                     │
  │                     └─ DMA、磁盘、网络、GPU
  v
系统调用、缺页、中断与上下文切换
1
2
3
4
5
6
7
8
9
10
11

这张图说明性能问题通常跨越多层。一次看似普通的数组遍历可能受编译器向量化、缓存行、页映射和 NUMA 放置共同影响;一次文件读取可能经过页缓存而没有真正访问磁盘;GPU Kernel 很快,也可能被主机到设备的数据传输抵消。学习时应持续追问:数据在哪里、由谁移动、执行单元在等待什么、观测指标来自哪一层。

推荐学习方式 ​

第一阶段先掌握进程、线程、虚拟内存、文件系统和 I/O,能解释程序获得资源以及隔离如何实现。第二阶段进入 CPU 流水线、缓存层次、SIMD、GPU SIMT 和内存一致性,理解相同算法为何在不同数据布局下表现悬殊。第三阶段学习线程、OpenMP、CUDA 与 MPI,把工作分解、同步、通信和负载均衡联系起来。最后进入性能工程,用实验设计和工具验证前面形成的假设。

每学习一个机制,都应做一个可以证伪的小实验。例如改变遍历顺序观察 Cache 行为,固定输入规模比较线程数,区分冷缓存与热缓存,或用采样 Profile 验证热点是否真的位于预期函数。实验需要记录硬件、编译参数、输入、预热、重复次数和统计方法,否则结果无法复现。

与其他大区的边界 ​

  • C++ 区讲 std::thread、原子和构建工具怎样使用;本区解释核心、Cache、SIMD、GPU 和 MPI 为什么这样工作。
  • AI Infra 讲训练系统;本区提供 CUDA、集合通信和硬件的通用基础。
  • 工业软件讲求解算法;本区提供数据局部性、并行模式和性能测量方法。

边界不是割裂。C++ 并发语义决定代码是否正确,硬件内存模型解释它为何需要同步;算法决定理论工作量,体系结构决定数据移动成本;部署系统给出资源限制,性能工程判断限制是否构成瓶颈。遇到跨区问题时,应从业务目标向下追踪,而不是为了使用某个工具而优化。

统一性能模型 ​

text
总时间 = 有效计算 + 数据移动 + 同步等待 + 调度开销 + I/O
1

先保证正确,再测量瓶颈,最后优化。CPU 利用率或 GPU Occupancy 等单个指标不能独立证明程序高效。

完整优化闭环是:定义用户可感知指标,固定代表性工作负载,建立基线,采集证据,提出一个可检验假设,只做最小改动,然后复测正确性、性能和资源成本。局部加速如果增加端到端延迟、破坏数值结果或让维护成本失控,就不属于成功优化。

学完本区后,读者应能画出程序从源代码到硬件执行的路径,选择合适的并行模型,判断测量是否可信,并用瓶颈证据解释优化有效或无效的原因。

最后更新于:

Pager
下一篇OS 底层知识学习路线 / A Learning Path for Operating System Internals

持续记录,持续成长

Copyright © Tidenflow