术语表
应用程序二进制接口(Application Binary Interface,ABI) API的编译代码实现。
阿姆达尔定律(Amdahl's law) 计算并行代码最佳性能的简单公式。最佳性能取决于硬件可用的并行度和代码串行占比。实际上,该定律给出了过于乐观的上界。
应用程序接口(Application Programming Interface,API) 程序与软件底层的稳定接口。软件底层可以是库,也可以是操作系统本身。
专用集成电路(Application Specific Integrated Circuit,ASIC) 针对特定功能或应用制备的非通用集成电路芯片。
BasicLockable C++标准中的命名要求,描述了可通过std::lock_guard使用的类。
缓存一致性(cache coherence) 机器中所有缓存对特定缓存行持有相同值的理想属性。
子任务(child task) 由父任务创建的任务。
代码(code) “程序”或“应用程序”的同义词。
一致性组构(coherence fabric) 承载核心与核心之间用于维持缓存一致性的消息的互连结构。
编译(compilation) 将程序的人类可读表示转换为一组可由计算机执行的机器指令(和数据)的行为。
核心(core) 请参见“物理核心”。
平均指令周期数(Cycles Per Instruction,CPI) 测量特定CPU实现的代码执行效率的方式。
中央处理器(Central Processing Unit,CPU) 请参见“核心”。但是在某些语境下,用CPU来指代物理封装,这种物理封装包含多个核心、缓存等。
后代任务(descendant task) 作为子任务的任务或作为后代任务的子任务的任务。
直接存储器访问(Direct Memory Access,DMA) 允许网络接口或硬盘控制器等设备直接访问内存,而无须用CPU从设备中移入或移出数据的技术。
伪共享(false sharing) 由于使用单个物理缓存行保存两个不相关的变量而发生的共享。伪共享导致缓存之间的传输。这会影响性能,但是,由于从变量到存储位置的映射是由编译器控制的,因此在源代码中难以发现该问题。
futex 用于挂起或唤醒线程的Linux系统调用。
硬件线程(hardware thread) 请参见“逻辑核心”。
初始线程(initial thread) 请参见“主线程”。
因特网协议(Internet Protocol,IP) 使不同机器能够通过因特网进行通信的底层协议。
进程间通信(InterProcess Communication,IPC) 在不同进程(可能位于同一台机器上,也可能是远程进程)之间进行通信的方法。IPC有时也用于表示“每周期指令数”(Instructions Per Cycle,IPC),即1/CPI,但本书中我们不使用此用法。
即时(Just-In-Time,JIT) 即时编译是一种在程序执行时对其进行编译的实现。即时编译避免了对离线编译的需求,并且允许编译器知晓编译目标机器,还利用了配置文件信息,以做出良好的优化选择。代价是每次运行代码时,都必须进行编译。
抖动(jitter) 由环境或同一系统上正在执行的其他进程和线程向系统注入的噪声。
后进后出时间(Last In Last Out time,LILO时间) 对于集合操作,LILO时间是指:从最后一个线程到达时开始,到最后一个线程离开时结束,其间经过的墙上时钟时间。对于树形同步障,LILO时间是指:合并和广播操作的后进根出(Last In Root Out,LIRO)时间与根进后出(Root In Last Out,RILO)时间的总和。
后进根出时间(Last In Root Out time,LIRO时间) 合并操作是指:单一的根线程发现所有线程都到达以后,只有根线程离开的操作。对于这种合并操作,LIRO时间是指:从最后一个线程到达时开始,到根线程离开时结束,其间经过的墙上时钟时间。
逻辑核心(logical core) 操作系统在其上调度工作的单一硬件执行线程。在同步多线程(Simultaneous Multi-Threading,SMT)机器中,逻辑核心是单一的SMT,而一个CPU或核心可以同时执行多个SMT。
逻辑CPU(logical CPU) 同“逻辑核心”。“逻辑CPU”术语来自Linux操作系统。
主线程(main thread) 在进程创建后,开始在进程中执行的那一个线程。
内存屏障(memory fence) 在乱序CPU中,对本地核心发出的内存指令强制进行外部可见排序的指令。
操作系统(Operating System,OS) 操作系统内核与库的组合。操作系统为用户代码提供了在机器上运行的途径,同时使用户代码从底层硬件复杂性中抽象出来。
操作系统内核(OS kernel) 操作系统中以特权模式执行、控制设备、提供文件系统、为用户级进程分配资源的部分。
封装(package) 请参见“处理器封装”。
并行占比(parallel fraction) 在串行代码中,能够并行执行的部分所占的时间比例。
父任务(parent task) 创建其他任务的任务。
物理核心(physical core) 执行指令的硬件实体。在SMT系统中,一个物理核心可以支持多个逻辑核心。有时简称为“核心”。
进程(process) 执行代码的保护域。一个进程至少包含一个线程。
处理器管芯(processor die) 包含处理器以及诸如缓存、内存控制器等支持基础设施的硅片。
处理器封装(processor package) 插入系统插槽的物理单元。处理器封装可包含多个管芯。
根进后出时间(Root In Last Out time,RILO时间) 对于广播操作,RILO时间是指:从根线程到达时开始,到最后一个线程离开时结束,其间经过的墙上时钟时间。
根线程(root thread) 在集中式集合操作(例如集中式同步障)中,作为中心线程的单一线程。它知晓其他线程是否都已到达。
sched_yield 进入并请求内核运行调度器,以运行适当线程的Linux系统调用。对于现代Linux内核,在轮询循环中调用sched_yield()是无效的,故请勿如此调用。
串行占比(serial fraction) 代码中必须串行执行的部分所占的时间比例。
兄弟任务(sibling task) 拥有相同父任务的任务。
插槽(socket) 在系统主板上,将处理器封装与计算机主板相连接的物理安装。该术语有时用作“处理器封装”的替代词。
任务(task) 在线程中拥有专属数据环境和执行代码的并发工作单元。
任务池(task pool) 存放正在等待被线程选中并执行的任务的容器。
任务队列(task queue) “任务池”的误用名称。
线程(thread) 单一执行实体,以及与其关联的状态。线程在进程内部执行。
线程池(thread pool) 一组即使没有工作也依然保持活跃的线程。有新工作时,能迅速启用它们。
volatile C语言的关键字之一。对该类型变量的每一次存储或加载操作都必须实际发生,以防止编译器认为没有必要而将操作优化掉。