本文目的是从 Prompt 到绘制到输出全链路数据结构、Tensor的生命周期,讲清楚“用户输入一句 prompt → KVCache 生成 → A 节点 → KVCache 传输 → B 节点恢复 → decode → detokenizer → 输出” ,在这条链路中涉及的核心数据结构、Tensor、转换/恢复点、生命周期与进程边界,尽可能详细地画出来。
本文目的是从 Prompt 到绘制到输出全链路数据结构、Tensor的生命周期,讲清楚“用户输入一句 prompt → KVCache 生成 → A 节点 → KVCache 传输 → B 节点恢复 → decode → detokenizer → 输出” ,在这条链路中涉及的核心数据结构、Tensor、转换/恢复点、生命周期与进程边界,尽可能详细地画出来。
PostgreSQL 项目历经二十多年,其软件开发准则和要求以严格著称,本文的目的是为了介绍一些PG社区的开发hints。也算是初入PG社区的一些随笔,好的软件开发不仅包含代码礼仪,还应该包含优雅简洁的邮件/交流礼仪。事实上,下面列出的一些礼仪不仅是在PG社区、也是其他开源社区应该学习和了解的典型范例,更是在科技行业使用邮件、Github、在任意平台讨论技术和代码的优秀准则。
verbs 是 RDMA 的底层编程接口,目的是通过一组 ibv_* 调用把用户读写任务(WR)提交到队列(QP),网卡按这些请求在不经过内核协议栈的前提下执行 SEND/RECV、RDMA READ/WRITE、原子操作 等动作,并把结果以完成事件(CQE)的形式回报给应用。
▸ 类比:BSD sockets 是用 TCP/UDP 传字节的系统调用集合,verbs 是用 RDMA 传内存的系统调用集合。sockets 交给内核协议栈;verbs 交给 RNIC 的硬件队列。
InfiniBand verbs 规范定义 HCA 能执行的动作(post、poll、create、modify等),因此在 Linux 用户态库中呈现为一组 ibv_* API。而不同厂商通过 provider(如 libmlx5、librxe)实现背后的具体硬件/软件行为,但对应用暴露统一的 verbs 抽象。
这也是为什么混装发行版包与第三方 OFED 会报错“符号找不到”,因为应用链接的 lib 库与内核驱动/provider 实现必须匹配。
RXE 是 Linux 上的“软件 RoCE v2 驱动”(内核模块 rdma_rxe),让普通以太网接口具备 RDMA 能力(走内核网络栈)。RoCE v2 将 RDMA 负载封装在 UDP/IPv4 或 UDP/IPv6 中,默认目的端口 4791。设备/驱动通常把到 4791 的流量识别为 RoCE。本文旨在用同一台主机、不依赖硬件 RNIC,搭出一套可复现且稳定的 RDMA 实验环境:rping、perftest均可跑通。
Sigmod 论文《Revisiting the Design of In-Memory Dynamic Graph Storages》阅读
本论文来自上海交大,论文主要关于内存中动态图存储(In-Memory Dynamic Graph Storage, DGS)设计的研究论文,论文核心是通过系统评估现有 DGS 方法,揭示其性能瓶颈并指明未来优化方向。动态图存储需支持并发读写,以满足实时图分析和更新需求。现有方法(如 LLAMA、Aspen、LiveGraph、Teseo、Sortledton 等)在读写支持、空间开销和并发控制上差异显著,但缺乏对这些维度权衡的系统研究。作者主要分析了现有系统的设计,以及讨论了如何针对 DGS 算法进行系统评估。
本文阅读该论文的重点一是仔细学习作者类比、分析、抽象系统的做法,二是借作者之手,对现在的 DGS 系统的发展做一个简单的了解。
论文链接 Revisiting the Design of In-Memory Dynamic Graph Storages
Sigmod 论文《Rethinking The Compaction Policies in LSM-trees》阅读
文章来自清华大学交叉信息学院,论文聚焦于 LSM 树的Compact策略优化,提出了一种名为 EcoTune 的动态规划算法,旨在通过重新思考Compact操作的定位,最大化系统的平均查询吞吐量。LSM 树的核心挑战在于通过将内存中的数据批量Flush到磁盘形成 “sorted string tables”,并定期Compact重叠的待合并SSTable以减少读放大(RA)。
传统Compact策略主要关注写放大(WA)与读放大的权衡,但忽略了现代存储设备的特性。现代 NVMe SSD 具备极高的写入带宽,写入性能不再是瓶颈。Compact与查询会竞争 CPU 和 I/O 资源,因此Compact策略的核心应是优化平均查询吞吐量,而非单纯降低瞬时读放大。
RocksDB-源码分析(1)BlockTable 读源码分析
本文讨论了RocksDB的Prefetch和Async机制,在回顾LevelDB的SSTable读流程基础上,深入分析RocksDB的BlockBasedTableReader读流程、Prefetch相关函数及异步读取机制,还介绍了相关类设计和简单测试结果。包括:
在ParquetReader的构造函数中,会打开文件句柄,加载元数据,并初始化。Scan函数负责实际的扫描过程,处理行组,应用过滤器,读取数据到DataChunk中。首先,在元数据加载部分,parquet文件的元数据通常位于文件末尾,包含schema、行组信息、统计信息等。LoadMetadata函数通过读取文件末尾的元数据部分,解析出FileMetaData结构。
DeriveLogicalType函数根据Parquet的SchemaElement中的类型信息(如Type、converted_type、logicalType)转换为DuckDB的LogicalType。例如,Parquet的INT32可能对应DuckDB的INTEGER,而带有converted_type为DATE的INT32会被转换为DATE类型。这里还处理了时间戳、UUID等复杂类型的转换。
创建列读取器的过程在CreateReaderRecursive中完成,这个函数递归地遍历SchemaElement树,根据每个元素的类型和子元素创建相应的ColumnReader。例如,遇到STRUCT类型时,会创建StructColumnReader,并为每个子列创建对应的读取器,对于重复的字段(如LIST或MAP),会使用ListColumnReader来处理嵌套结构。
初始化时,InitializeSchema调用CreateReader创建根读取器,通常是StructColumnReader,因为它对应Parquet文件的根结构。然后根据读取到的列信息填充columns向量,记录每个列的名称和类型。
扫描数据的过程由Scan函数处理。ParquetReaderScanState用于跟踪扫描的状态,包括当前处理的行组、文件句柄、过滤器等。PrepareRowGroupBuffer函数准备当前行组的数据,可能应用统计信息进行过滤,跳过不需要读取的行组。然后通过ColumnReader的Read方法将数据读取到DataChunk中,应用过滤器(如果有的话),最终将结果返回。
过滤器处理部分,ApplyFilter函数根据过滤条件对读取的数据进行过滤。例如,等值比较、范围比较、IS NULL等条件会被应用到数据上,减少需要处理的数据量,提升查询性能。
先看代码:
1 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64" |
DWARF全称为“Debugging With Attributed Record Formats”,其设计初衷是为了配合ELF格式进行UNIX可执行文件的调试信息生成。DWARF调试信息主要面向开发者用以指导如何生成调试信息以及如何使用调试信息。比如编译器、链接器开发者需要参考DWARF来生成调试信息,而调试器开发者需要参考DWARF来使用调试信息。DWARF开始时主要是为 UNIX 下的调试器提供必要的调试信息,例如内存地址对应的文件名以及代码行号等信息。GCC和Clang以及Go和Rust都使用该格式生成调试信息,与该格式相对的,Windows平台使用PDB(Program Database)作为调试信息的主要格式。
2017年,DWARF v5发布,提供了更好的数据压缩能力,调试信息与可执行程序的分离,对macro宏和源代码文件的更好的描述以及更快速的符号搜索、还有对编译器优化后代码的更好描述等等。
Update your browser to view this website correctly.&npsb;Update my browser now