分布式系统(E08):从微秒 RPC 到尾延迟追踪
一次请求的平均延迟很低,p99却不断升高。trace瀑布图里某个服务占了四十毫秒,于是它被判为根因。这个诊断可能同时错在三处:请求要等待的完成条件没有写清,压测器在慢响应期间停止发新请求,跨主机时间戳又被当成了因果顺序。 eRPC说明了专用数据中心RPC如何把软件开销压低;尾延迟研究解释了罕见慢节点怎样进入用户请求;分布式追踪负责保留单次执行的关系证据。这三者解决的问题相邻,却不能彼此替代。 分布式系统(E07):控制面共识与数据面复制 延迟样本由三段协议共同产生 端到端延迟不是某个函数自带的属性。请求路径规定要等哪些分支,负载发生器决定请求何时进入,观测管线再决定哪些阶段留下记录。 flowchart LR A[到达模型<br/>何时产生请求] --> P[执行路径<br/>串行、fan-out、quorum] P --> Q[队列与服务<br/>等待、计算、重试] Q --> O[观测管线<br/>span、metric、profile] O --> J[结论<br/>分位数与...
深入 Elasticsearch(08 补充):查询为什么没命中
I don't have a key. 放进 Elasticsearch 以后,输入 don't have 为什么有时能查到、有时必须写成 "don't have"?这个问题不能只靠记住 match、term、fuzzy 的名字来解决。一次查询至少跨过四层:字段怎样建、文本怎样变成词项、输入采用哪种查询语法、命中的文档怎样排序。四层中任何一层不同,结果都会不同。 判断一条字符串查询前,按这个顺序检查:字段能力 → 词项 → 查询语言 → 查询类型与上下文。不要先猜“ES 的模糊匹配是不是失效了”。 本文用同一条文档贯穿所有例子: 1234{ "message": "I don't have a key.", "status": "open"} 这里的“全文检索”默认指 Elasticsearch 的词法全文检索:把文本变成词项,再在倒排索引里检索。它不会默认按语义距离找近义句子;向量检索、semantic_text 或 kNN 才属于另一条显式...
计算机体系结构 27:NUMA 与数据放置
计算机体系结构 27:NUMA 与数据放置 核心问题 虚拟地址分配成功时,物理页是否已经落在某个 NUMA 节点?通常不能这样判断。Linux 的 NUMA policy 约束页面分配选择,但匿名页常在首次触发实际分配时才获得物理页。线程在哪个 CPU 上触页、策略允许哪些节点、页面后来是否迁移,都会改变数据位置。 本篇用双节点手算说明本地页和远端页怎样改变访问成本。当前环境没有 NUMA 拓扑、CPU 绑定、驻留页或迁移的真机证据。 附件:27-numa.json。 范围与证据等级 题设只有两个节点。本地页访问成本定为 100 ns,远端页定为 170 ns;这两个数是模型输入,不是从当前主机测得。模型按访问次数加权求和,不模拟队列、互联拥塞、缓存命中、预取、页大小差异或内存带宽。 证据等级是手算。Python 只负责复算和保存结果,不能把它升级为教学时序模型或真机测量。 policy、绑定与驻留是三件事 Linux NUMA policy 可以作用于 system、task、VMA 或 shared mapping。task policy 通常影响之后发生的页分配;修改策略不...
计算机体系结构 26:并行程序的扩展上限
计算机体系结构 26:并行程序的扩展上限 核心问题 线程数翻倍,运行时间为什么很少恰好减半?固定问题规模时,可并行部分只是上限的一项。线程创建与归约会增加额外工作,共享缓存和内存通道会引入竞争,任务划分还可能让部分线程提前空闲。 本篇只分析强扩展:总工作量固定为 300000 次写入,线程数取 1、2、4。它回答当前宿主上的样本怎样读,不把一次短基准外推成处理器的固定扩展率。 附件:26-scaling.json。 范围与证据等级 实验包含三组工作负载。independent 把不同下标分给不同线程;compact 让线程更新相邻的 C11 relaxed 原子计数器;spaced256 把计数器间距扩大到 256 字节。每个组合运行 5 次,计时覆盖 pthread_create 和 pthread_join,每次都校验结果。 证据等级为真机测量,但结论只适用于当前 Linux x86-64 宿主、固定输入和本次进程状态。没有绑核、固定频率、PMU、缓存缺失计数或内存带宽计数,因此不能把耗时变化归因为某个硬件事件。 理想上限为什么不等于测量结果 若串行占比为 s,并行部分能被 ...
计算机体系结构 28:SMT 与共享资源
计算机体系结构 28:SMT 与共享资源 核心问题 单线程因为依赖或 cache miss 暂时不能发射时,执行槽会空着。细粒度多线程可以每周期换一个线程,减少整段空闲;同时多线程(SMT)还能在同一周期从多个线程挑选指令填充多个槽。它提高的是共享资源利用率,不会自动增加执行单元、cache 容量或互联带宽。 本篇用宽度为 2 的有限发射模型区分三种调度。当前主机没有硬件 SMT、逻辑兄弟线程或 PMU 证据。 附件:28-smt.json。 范围与证据等级 模型给两个线程各一条短指令流,其中包含 wait。单线程模式只运行 A;细粒度模式每拍只能从一个线程发射;SMT 模式允许同拍从 A、B 各取一条,但总发射宽度仍为 2。 证据等级是教学时序模型。它没有 ROB、cache、分支预测、物理寄存器、真实 NoC、线程优先级或公平性策略,因此只能解释“空槽怎样被另一线程利用”。 核心案例:发射宽度不等于可用吞吐 两个槽在某拍都空闲,不代表单线程一定能填满。若线程 A 的下一条指令等待前序结果,它不能凭空提供第二条就绪指令。线程 B 若有独立工作,SMT 调度器可以用 B 填其中一...
计算机体系结构 29:CPU 怎样与设备交换数据
计算机体系结构 29:CPU 怎样与设备交换数据 核心问题 设备完成一次 DMA 后,CPU 为什么还不能立刻把缓冲区当成普通内存读取?数据移动只是传输链路的一部分。驱动还要处理 DMA 地址映射、缓冲区所有权、完成通知和同步;IOMMU 则可能在设备地址与物理内存之间再加一层翻译和权限检查。 本篇只验证一条六状态协议,不连接真实设备,不产生总线事务,也不测中断延迟。附件:29-dma.json。 范围与证据等级 证据等级为功能执行。模型依次进入 cpu_owned、mapped_for_device、device_owned、completion_visible、synced_for_cpu、cpu_consumed。这些状态用于检查“谁此时可以访问缓冲区”,不能证明某个平台的 DMA 一致性实现,更不能称作真实设备传输。 Linux Dynamic DMA Mapping Guide 区分 CPU 虚拟地址、CPU 物理地址和设备使用的 DMA 地址。驱动应使用 DMA API 建立映射,不能把 CPU 指针直接交给设备。streaming mapping 的同步要求还取决于...
计算机体系结构 30:SIMD 与向量化边界
计算机体系结构 30:SIMD 与向量化边界 核心问题 编译器报告循环已向量化,怎样确认它没有改坏数值,也没有漏掉不能整除向量宽度的尾部?至少要同时保留源码、严格 CLI 验证、逐元素检查、墙钟原始样本、二进制身份和反汇编。 附件包括 30-simd.json、simd_bench.c、二进制检查、标量反汇编和向量反汇编。 范围与证据等级 证据等级为真机测量。GCC 13.3.0 在当前 Linux x86-64 宿主编译同一浮点加法内核:标量版使用 -fno-tree-vectorize,向量版使用 -ftree-vectorize -fopt-info-vec-optimized。没有绑核、固定频率或 PMU,因此墙钟值只描述本次宿主样本。 CLI 接受 N REPS ROUNDS,每个参数均做完整字符串解析和范围检查。N=4099、REPS=500、ROUNDS=5;4099 不能被实际观察到的 4 个 float lane 整除,留下 3 个尾元素。 核心案例:产物、结果与尾部必须同时成立 编译报告记录 16 字节和 8 字节向量化版本。向量反汇编的内核含 addps,尾...
计算机体系结构 31:GPU 执行与合并访存
计算机体系结构 31:GPU 执行与合并访存 核心问题 32 个线程发出 32 次访存,为什么不能直接说成 32 次显存事务?GPU 会按活跃线程、地址分布和架构规则组合请求。分支还会改变每条路径上的活跃掩码,因此源码线程数、模型段数和硬件事务数是三种不同口径。 本篇用 32 lane、32 字节段的题设手算地址覆盖。附件:31-gpu.json。 范围与证据等级 证据等级为手算。题设假定一个 warp 有 32 个 lane,并把地址所属的 floor(address / 32) 段数作为比较指标。它没有运行 CUDA kernel,没有采集 GPU 周期、occupancy、cache hit 或真实 memory transaction 计数。 NVIDIA CUDA C++ Programming Guide 定义 warp 的 SIMT 执行语义;Best Practices Guide 说明全局内存访问合并与设备计算能力和地址分布有关。本篇的 32 字节分段只是明确题设,不能覆盖所有代际的实际事务规则。 核心案例:连续、跨步与错位地址 每个 lane 读取一个 4 字...
计算机体系结构 32:Roofline 与矩阵数据复用
计算机体系结构 32:Roofline 与矩阵数据复用 核心问题 分块矩阵乘法减少了某一层级的数据搬运,性能就一定提高吗?Roofline 先用运算强度把计算峰值和带宽上界放在同一坐标系中,但模型上界不是实测性能点;字节流量还必须注明针对 DRAM、缓存还是片上 scratchpad。 附件:32-roofline.json。 范围与证据等级 证据等级为手算。题设峰值为 128 GFLOP/s,带宽为 32 GB/s。两个模型点的运算强度分别是 0.25 和 8 FLOP/byte,均未在当前主机或加速器上测量。 Williams、Waterman 与 Patterson 的 Roofline 模型用下式表达可达到性能的上界: 1attainable <= min(peak compute, peak bandwidth × operational intensity) 公式中的 peak 和 bandwidth 必须来自同一机器与相符的测量口径;operational intensity 的字节分母也要固定内存层级。 核心案例:同一计算量,不同数据复用 朴素模型点的运算强...
计算机体系结构 34:有界处理器集成
计算机体系结构 34:有界处理器集成 核心问题 参考执行、流水线时序和缓存延迟接在一起后,怎样证明加速结构没有改变程序的提交结果?最小可检查条件是:参考模型与流水线产生同序、同值的提交事件;延迟只改变周期;故意移除正确性机制时,差分检查必须失败。 附件:34-integration.json和模型源码。 范围与证据等级 证据等级为教学时序模型。当前恢复模型只执行五条指令,支持本案例所需的 addi、lw、add、sw 和 halt。它没有实现完整 RV32I、异常、MMU、乱序、多核或真实 DRAM。 缓存只有两行,每行 16 字节,记录 tag、命中、缺失和固定 miss 延迟。数据值仍由架构 memory 字典提供,因此模型没有验证完整的 write-back 数据层级,也没有证明脏块最终到达 DRAM。 核心案例:结果相同,时间不同 初始 memory[16]=7。程序把 16 写入 x1,从地址 16 读取 7 到 x2,计算 x3=14,再把 14 写到地址 32。参考执行和流水线提交序列均包含五个事件,最终 x2=7、x3=14、memory[32]=14。 两次访存...









