当前位置: 首页 > news >正文

从一到无穷大 #51:突破阿姆达尔定律:COZ因果剖析与串行优化八法

在这里插入图片描述本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。

文章目录

  • 引言
  • 串行优化的原则和方法
  • COZ
  • 结束语

引言

本来这周末打算看下Fuzzing Test相关的点,但是在简单浏览了USENIX ATC 2024 的WingFuzz后,发觉需要写一点代码来验证一些想法,我并不是排斥去做一个小的原型,只是恰逢关键时间节点,整个人懒洋洋的,实在是不想动脑子,其次工作中遇到了一些代码上难解的问题,整个人也并不想在解决工作问题前浪费过多心力,遂选择了SOSP2015 COZ: Finding Code that Counts with Causal Profiling 和 OSDI2025 Principles and Methodologies
for Serial Performance Optimization两篇优化相关的论文放松下疲惫的大脑。

其实算着时间今天是完不成这篇随笔的,因为今天下午六点组了去深圳湾踢球的局,回家不知道是什么时候了,可惜又逢暴雨天,也正好是给了我机会完成这篇文章。

也不知是不是真的懈怠,写完上面这句就去小房间刷短视频了,随着女朋友奶声奶气的“诶呀,现在家里还有一个人在学习,不要吵”,哈哈哈,好吧,还是写完这篇文章再去刷短视频吧。

性能优化长久以往的“标准范式”便是基于oprofile, perf, gprof 生成火焰图,然后基于开发人员对于代码的熟练程度,领域知识与创造性,给出性能优化的方法,然后实施性能优化,检查是否符合预期,循环往复。

这里面有几个问题,基于工具找到热点后,修复是否可以判断可以真的提升性能?优化单个函数,操作对于整体执行的优化有多少(瓶颈转移)?优化本身除了基于工程师的创造力是否有通用模版可以使用?

上述问题的答案都是:是

设想未来整个优化流程——从性能监测,解决方案设计,代码生成,性能评估——都将实现自动化。

  1. Continuous Profiling + LLM:自动性能瓶颈发现,生成采样范围
  2. COZ:确定热点优化对于全局的影响,找到有效的优化点
  3. LLM + sysGPT + Prompt:分析代码给出现有的实现方式,给出串行代码性能优化建议,并生成详细的Prompt
  4. Claude-4-sonnet:高质量代码生成

以华为的CodeArts Doer为例,其实现了六个Agent,覆盖了软件周期的全流程:

  1. 团队助手Agent(Timmy):定义项目目标,分解任务为“前端开发”和“后端开发”。
  2. 产品助手Agent(Pony):输入需求“开发一个用户登录页面”,生成需求文档。
  3. 开发助手Agent(David):在IDE中输入“用户登录页面代码”,生成HTML和JavaScript代码。
  4. 测试助手Agent(Cindy):输入测试需求“测试用户登录功能”,生成测试用例并执行测试。
  5. Committer助手Agent(Oliver):提交代码前,进行代码质量检查,确保代码符合规范。
  6. 项目管理与监控Agent(Mike):跟踪项目进度,监控项目风险。

基础理论已经具备,按照这个思路,后续性能优化Agent,监控Agent(告警智能分析,也会衍生出对底层监控基础设施的更高要求)也会如雨后春笋般涌现。

确实只会代码的初级工程师存在的必要被大幅度降低了。

串行优化的原则和方法

根据阿姆达尔定律(Amdahl’s law )[5],一个程序的性能最终受限于其必须串行执行的部分。

尽管现在有很多并行计算技术,但优化串行任务仍然是实现显著性能提升的关键。然而,性能优化的过程往往依赖于工程师的直觉和个人经验,缺乏一套系统化的理论和方法来指导实践

提升顺序工作负载的系统性能可以看做:优化任务序列SnS_nSn,以最终减少运行时间F(Sn)F(S_n)F(Sn)。这样来看的话有三种策略性方法:

  1. 移除某个任务
  2. 序列中的任务为更快的实现
  3. 对任务重新排序

论文对过去十年OSDI和SOSP发表的477篇文章执行分类,提炼其优化成果,结果表示下面八种思路概括了所有的优化方式:

  1. batching
  2. caching
  3. precomputing
  4. defering
  5. relaxation
  6. contextualization
  7. hard-ware specialization
  8. layering:这个概念比较泛,Bypassing,Delayering,Decoupling都被归类到这一类中

请添加图片描述

请添加图片描述
271篇文章不涉及顺序性能优化,剩下的优化方案都可以被归类到八种方法中来。

仔细一想我们团队这些年来做的优化,确实都可以被归类进来,这事实上给了我们在做性能优化时一个方向,比如现在我们做了哪些事情,如果还有没有命中这八种中的某一种,就可以往上靠下。

论文中其实也是这个思路,总结了2013-2022的全部论文,对GPT-4o做了微调,称为sysGPT。
在这里插入图片描述

COZ

SOSP2015的最佳论文奖,其对于分析过程称为Causal Profiling,羡慕人家的造词能力。

请添加图片描述

其关键洞察是现有的性能分析工具存在弊端:

  1. 误导性指示:某段代码执行时间长,并不意味着优化它能提升整体性能。例如,在文件下载时显示加载动画的代码可能与下载代码耗时相近,但优化加载动画对整体执行时间无影响。
  2. 并行程序盲区:在多线程程序中,传统工具难以识别关键路径。如图 1 所示的多线程程序中,函数a()和b()分别耗时 6.7 秒和 6.4 秒,传统工具(如 gprof)会报告两者占比相近(55.20% 和 45.19%),但实际上完全优化a()仅能提升 4.5% 性能(因b()成为新瓶颈),优化b()则无效果。
  3. 无法量化优化潜力:传统工具仅报告现状,无法预测优化某段代码的具体效果,开发者需依赖自身对程序的理解推测

不妨我们自己先想想,如何衡量优化了一段代码后全局性能是否有提升呢?

  1. 很显然代码必须要跑起来,不然没法衡量对于全局的影响;
  2. 其次当前代码还没实现加速,自然没法知道加速后对于其他代码的影响
  3. 那么当前代码的时延是固定的,那么其他代码执行的慢一点就相对快了,就可以达到这个效果
  4. 使用Ptrace监控进程,统计到这一段代码的执行数N和执行时间T,NT就是这段代码的总执行时间,那么其他代码只要总体慢个NT*0.5,那么就相当于这段代码加速了50%了
  5. 最简单的思路就是触发指定代码段的时候其他线程就sleep,但是可能会触发非常多次,这就导致其他线程要频繁sleep
  6. 如果能采样,把N次执行合并成一次Sleep让其他线程执行就好了

以上就是论文的核心Virtual Speedup
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. n是代码的执行总数
  2. P事采样周期
  3. t是一次的执行时间
  4. s是采样到需要加速的次数(其他线程sleep)
  5. 最终△t就是实际加速的比例,与P有关,d是一次加速的时间,所以如果想要加速25%,就插入一个采样周期四分之一的时延

这个公式非常重要。

我简单玩了下COZ这个项目,只能说年老失修,主代码已经两三年没动过了,甚至于代码分析的页面也会直接跳转到github首页。

公司的开发机上并没有现成的包,好在整个项目并不难部署,web的部署也比较简单,就是没有教程,我解决以后顺便回馈社区了[7]:

在这里插入图片描述

cd viewer && python3 -m http.server 8080 部署COZ web的方式
./coz run — ./benchmarks/sqlite-modified/sqlite-bench-modified

可以看到还是可以比较清晰的看出应该优化哪些代码的,但是这个思路在大型项目中是否有效我持怀疑态度,因为线程太多了,引用各种各样的三方库,有着各种各样的线程管理,这里如果可以分析出哪些现成线程终止有影响,哪些线程终止没有影响就好了,但是现阶段比较像玩具,无法在工业界大规模使用,也好理解,毕竟是学术成果不是工业界验证多年的。

结束语

感叹我们正处于巨大的变革当中,奇点的到来也并不温和,自ChatGPT发布仅三年时间,行业的发展已经是沧海桑田,但好在基础架构还是足够稳健,混口饭吃短时间看倒不是问题。

参考:

  1. CodeArts Doer 智能助手
  2. AI Coding 又进化了!王炸!
  3. SOSP2015 COZ: Finding Code that Counts with Causal Profiling
  4. OSDI2025 Principles and Methodologies for Serial Performance Optimization
  5. 阿姆达尔定律
  6. plasma-umass coz
  7. cos issue 255
http://www.dtcms.com/a/313425.html

相关文章:

  • Java学习第一百零一部分——网关(Gateway)
  • java测试题(ssm框架)
  • 02.Redis 安装
  • MPLS 静态LSP
  • TV电视版软件集合分享
  • 深入理解Java并发编程:原理、实战与最佳实践
  • Redis 7 中的 Set 和 Zset 使用
  • 基于transformer的目标检测——匈牙利匹配算法
  • 深入解析HashMap:原理与性能优化
  • Vim编辑器详解:从入门到高效使用
  • 从零开始的CAD|CAE开发: LBM源码实现分享
  • 编程语言分类
  • JAVAEE--5.多线程之常见的锁策略
  • AI Competitor Intelligence Agent Team
  • 【openlayers框架学习】七:绘制线要素以及点击画线功能
  • 力扣热题100----------141.环形链表
  • 基于BiLSTM+CRF实现NER
  • 【机器人】VLN-R1 微调 | 增强训练 | 连续导航
  • Web3合约ABI,合约地址生成部署调用及创建,连接钱包,基础交易流程
  • ARPO:让LLM智能体更高效探索
  • 【Linux网络编程基础--socket地址API】
  • 多 4G 通讯模组共存时的干扰问题深度解析与解决方案
  • leecode-每日一题-2106. 摘水果
  • vmfusion启动centos6.10 一直卡到call 169.254.169.254
  • 全面解析 BGE Embedding 模型:训练方式、模型系列与实战用法
  • Redis——常用指令汇总指南(三)(哈希类型)
  • 编写xsync集群分发脚本(保姆级别)
  • Redis 数据同步机制
  • 【Linux】Makefile Cmake—基操
  • [特殊字符]字节Get!免费进楼攻略速存[特殊字符]