<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Yrom&#39;s</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://yrom.net/"/>
  <updated>2026-04-21T15:48:13.814Z</updated>
  <id>https://yrom.net/</id>
  
  <author>
    <name>Yrom</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Advisor Strategy 里最难实现的是弱模型的「自知之明」</title>
    <link href="https://yrom.net/blog/2026/04/21/advisor-pattern-metacognition/"/>
    <id>https://yrom.net/blog/2026/04/21/advisor-pattern-metacognition/</id>
    <published>2026-04-21T15:10:00.000Z</published>
    <updated>2026-04-21T15:48:13.814Z</updated>
    
    <summary type="html">
    
      &lt;!-- # Advisor Pattern 的真正护城河，不是 API 设计，是弱模型的&quot;自知之明&quot; --&gt;

&lt;p&gt;4 月 9 号，Anthropic 发了个特别的功能 &lt;a href=&quot;https://claude.com/blog/the-advisor-strategy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Advisor Strategy&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/agent-advisor-strategy.png&quot; alt=&quot;Advisor Strategy&quot;&gt;&lt;/p&gt;
&lt;p&gt;让学生姜维 Sonnet 或 Haiku 先跑任务，遇到搞不定的再请诸葛亮 Opus 出山。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/Claude-Blog-Advisor-tool-SWE-bench-Multilingual.png&quot; alt=&quot;SWE-bench-Multilingual&quot;&gt;&lt;/p&gt;
&lt;p&gt;官方跑分数据很亮眼。&lt;code&gt;Sonnet + Opus advisor&lt;/code&gt; 在 &lt;em&gt;SWE-bench Multilingual&lt;/em&gt; 上比 &lt;code&gt;Sonnet&lt;/code&gt; 单独跑高了 2.7pp，&lt;em&gt;成本反而降了 11.9%&lt;/em&gt;。&lt;code&gt;Haiku + Opus&lt;/code&gt; 更夸张，BrowseComp 从 19.7% 飙到 41.2%，成本比 &lt;code&gt;Sonnet&lt;/code&gt; 单独跑还低 &lt;em&gt;85%&lt;/em&gt;。&lt;/p&gt;
&lt;p&gt;激活的方式很简单：&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;response = client.messages.create(&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    model=&lt;span class=&quot;string&quot;&gt;&quot;claude-sonnet-4-6&quot;&lt;/span&gt;,  &lt;span class=&quot;comment&quot;&gt;# executor&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    tools=[&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&quot;type&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;advisor_20260301&quot;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;advisor&quot;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&quot;model&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;claude-opus-4-6&quot;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&quot;max_uses&quot;&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;# ... your other tools&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    messages=[...]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Advisor tokens reported separately&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# in the usage block.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;p&gt;你往 Claude 模型 API 的 &lt;code&gt;tools&lt;/code&gt; 数组里加一个 &lt;code&gt;advisor_20260301&lt;/code&gt;，完事。整个过程在单次 API 调用内完成，不需要额外的编排层，不需要你自己管理上下文传递。&lt;/p&gt;
&lt;p&gt;听起来很美对吧？&lt;/p&gt;
&lt;p&gt;但仔细想想，似乎有个被忽略的关键问题：&lt;strong&gt;Sonnet 怎么知道什么时候该请教 Opus？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;毕竟，熊将之所以熊，就是熊在盲目做决策上，如果有「自知之明」肯请教军师，那还能熊哪去？&lt;/p&gt;
&lt;h2 id=&quot;反套路的编排模式&quot;&gt;&lt;a href=&quot;#反套路的编排模式&quot; class=&quot;headerlink&quot; title=&quot;反套路的编排模式&quot;&gt;&lt;/a&gt;反套路的编排模式&lt;/h2&gt;&lt;p&gt;Multi-Agent 编排大家天然都是用强的lead弱模型：强模型（Opus）当指挥官，做plan、拆任务，分给小模型（Sonnet/Haiku）去执行。&lt;/p&gt;
&lt;p&gt;但这个 Advisor Strategy 把逻辑翻转了：轮到弱模型当carry全程输出，强模型只当辅助。&lt;/p&gt;
&lt;p&gt;Sonnet 自己决定调工具、写代码、迭代循环，95% 的工作量都在 Sonnet 完成。只有当 Sonnet 遇到它自己判断搞不定的决策时，才在服务端内部触发一次 Opus 推理，拿到 400-700 tokens 的建议，然后继续。&lt;/p&gt;
&lt;p&gt;但这里有个隐含假设：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sonnet 能准确判断”这个任务我搞不定”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但这个判断题本身就是个很难的题目，好比你判断自己不知道什么，这比”知道自己知道”难多了。这就是所谓的 meta-cognition（元认知）——一个模型对自身能力边界的感知。&lt;/p&gt;
    
    </summary>
    
      <category term="AI" scheme="https://yrom.net/categories/AI/"/>
    
    
      <category term="AI" scheme="https://yrom.net/tags/AI/"/>
    
      <category term="Agent" scheme="https://yrom.net/tags/Agent/"/>
    
      <category term="LLM" scheme="https://yrom.net/tags/LLM/"/>
    
      <category term="Anthropic" scheme="https://yrom.net/tags/Anthropic/"/>
    
      <category term="Advisor Strategy" scheme="https://yrom.net/tags/Advisor-Strategy/"/>
    
      <category term="Metacognition" scheme="https://yrom.net/tags/Metacognition/"/>
    
  </entry>
  
  <entry>
    <title>提示词能被复制，你的产品不能</title>
    <link href="https://yrom.net/blog/2026/04/20/ai-agent-prompt-not-moat/"/>
    <id>https://yrom.net/blog/2026/04/20/ai-agent-prompt-not-moat/</id>
    <published>2026-04-20T14:10:00.000Z</published>
    <updated>2026-04-21T13:56:31.177Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;如果你正在做 Agent 产品，可能也面临一个问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我跟 LLM 搏斗了好几周甚至几个月，Prompt 调了十几版，Skill 也精心打磨了好几轮。要不要想办法防用户逆向提取提示词，保护 AI Agent 产品“知识产权”？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个问题乍一听既合理也紧迫。&lt;/p&gt;
&lt;p&gt;好比传统软件/手机应用，&lt;strong&gt;源代码绝对是核心资产&lt;/strong&gt;，有一系列反调试、加混淆、加壳等保护防逆向的工具链。&lt;/p&gt;
&lt;p&gt;那 AI 时代，Agent “源代码”似乎就是Prompt 和 Skill 那堆markdown 文本，毕竟市面上没几个能自己炼模型的对吧，大家都是LLM API Wrapper。这么类比，Prompt 和 Skill 是不是也该保护起来？&lt;/p&gt;
&lt;p&gt;我研究了一圈，结论是：这个问题本身就是站不住脚的。&lt;/p&gt;
&lt;h2 id=&quot;Why？技术上防不住&quot;&gt;&lt;a href=&quot;#Why？技术上防不住&quot; class=&quot;headerlink&quot; title=&quot;Why？技术上防不住&quot;&gt;&lt;/a&gt;Why？技术上防不住&lt;/h2&gt;&lt;p&gt;GitHub 上有仓库专门收集各大 AI 产品的泄露系统提示词。&lt;a href=&quot;https://github.com/asgeirtj/system_prompts_leaks&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;asgeirtj/system_prompts_leaks&lt;/a&gt; 有 38K+ stars，20.2K stars的&lt;a href=&quot;https://github.com/elder-plinius/CL4R1T4S&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;elder-plinius/CL4R1T4S&lt;/a&gt;，136K+ stars &lt;a href=&quot;https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;x1xhlol/system-prompts-and-models-of-ai-tools&lt;/a&gt; 。这些仓库覆盖了 ChatGPT、Claude、Gemini、Grok 等一众在线的、本地的 AI 产品，有些连 JSON tool schema 和版本历史都被扒出来了。&lt;/p&gt;
&lt;p&gt;Patrick Koss 看完这些泄露的提示词后总结：各家产品的系统提示词结构惊人地相似，都是”角色声明 + 工具列表 + 安全规则 + 输出格式”这个套路（&lt;a href=&quot;https://medium.com/@patrickkoss/stolen-blueprints-what-we-learned-from-leaked-ai-system-prompts-6fbd8a3996d2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Patrick Koss, “Stolen Blueprints: What We Learned From Leaked AI System Prompts”&lt;/a&gt;）。&lt;/p&gt;
&lt;p&gt;OWASP 专门出了个 &lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/LLM_Prompt_Injection_Prevention_Cheat_Sheet.html#best-practices-checklist&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Cheat Sheet&lt;/a&gt; 教你怎么在 prompt 里写”不要透露你的指令”，然后自己在同一份文档里承认：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Research shows that existing defensive approaches have significant limitations against persistent attackers due to power-law scaling behavior…”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;是的，从根本上就防不住。&lt;/p&gt;
    
    </summary>
    
      <category term="扯淡" scheme="https://yrom.net/categories/%E6%89%AF%E6%B7%A1/"/>
    
    
      <category term="AI" scheme="https://yrom.net/tags/AI/"/>
    
      <category term="Agent" scheme="https://yrom.net/tags/Agent/"/>
    
      <category term="LLM" scheme="https://yrom.net/tags/LLM/"/>
    
      <category term="思考" scheme="https://yrom.net/tags/%E6%80%9D%E8%80%83/"/>
    
      <category term="Prompt Engineering" scheme="https://yrom.net/tags/Prompt-Engineering/"/>
    
  </entry>
  
  <entry>
    <title>AI 时代，学得慢，就是快？</title>
    <link href="https://yrom.net/blog/2026/04/01/learn-slow-learn-fast/"/>
    <id>https://yrom.net/blog/2026/04/01/learn-slow-learn-fast/</id>
    <published>2026-04-01T15:00:00.000Z</published>
    <updated>2026-04-01T16:36:41.569Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;今天看到雷叔写故事公众号&lt;a href=&quot;https://mp.weixin.qq.com/s/dCnmmg1x_BJU_C-BvBOtrg&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;文章&lt;/a&gt; 引用了一个颇具“振聋发聩”的说法：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“AI 时代，只要你学得够慢，你就不用学了。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/images/ai-slow-is-fast.webp&quot; alt&gt;&lt;/p&gt;
&lt;h2 id=&quot;屠龙术&quot;&gt;&lt;a href=&quot;#屠龙术&quot; class=&quot;headerlink&quot; title=&quot;屠龙术&quot;&gt;&lt;/a&gt;屠龙术&lt;/h2&gt;&lt;p&gt;确实，AI 发展太快了，“AI一日，世间三年”。各种名词、热点，层出不穷。&lt;/p&gt;
&lt;p&gt;举个例子：XXX Engineering。从一开始 Prompt Engineering，到 Context Engineering，现在又 Harness Engineering。&lt;/p&gt;
&lt;p&gt;我曾经还研究过：“Vibe Engineering”，“Memory Engineering”。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/vibe-engineering.png&quot; alt=&quot;Vibe Engineering&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/agents-memory-engineering.png&quot; alt=&quot;Memory Engineering&quot;&gt;&lt;/p&gt;
&lt;p&gt;这种感觉像在追赶潮流，埋头苦练，回头看发现原来学的是屠龙术。&lt;/p&gt;
&lt;p&gt;剑法精妙，步法飘逸，炉火纯青。&lt;/p&gt;
&lt;p&gt;问题只有一个：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;龙不存在。&lt;/strong&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="扯淡" scheme="https://yrom.net/categories/%E6%89%AF%E6%B7%A1/"/>
    
    
      <category term="AI" scheme="https://yrom.net/tags/AI/"/>
    
      <category term="思考" scheme="https://yrom.net/tags/%E6%80%9D%E8%80%83/"/>
    
  </entry>
  
  <entry>
    <title>当 Token 成为新生产资料：程序员的价值正在归零？</title>
    <link href="https://yrom.net/blog/2026/03/23/token-as-new-capital/"/>
    <id>https://yrom.net/blog/2026/03/23/token-as-new-capital/</id>
    <published>2026-03-23T14:00:00.000Z</published>
    <updated>2026-03-24T01:43:16.102Z</updated>
    
    <summary type="html">
    
      &lt;!-- # 当 Token 成为新生产资料：程序员的价值正在归零？ --&gt;
&lt;p&gt;&lt;img src=&quot;/images/live-or-die.jpg&quot; alt=&quot;Live or Die&quot;&gt;&lt;/p&gt;
&lt;p&gt;最近我常在想一个 Live or die 的问题：&lt;strong&gt;作为程序员，我们赖以生存的本钱到底是什么？&lt;/strong&gt; 换句话说，老板凭什么为此而掏腰包？&lt;/p&gt;
&lt;p&gt;是能写那一大段自诩优雅而简洁的 Effective Modern C++ 代码吗？还是靠踩坑磨炼出来的对复杂系统的工程直觉？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/effective-modern-cpp-cover.png&quot; alt=&quot;Effective Modern C++&quot;&gt;&lt;/p&gt;
&lt;p&gt;之前，我觉得程序员这活是存在入行门槛的，好歹是个脑力劳动，至少智力水平得在线，那么撬动老板付钱的本质是”智力杠杆”，越聪明的人能力天花板越高舞台越大自然也就越贵。&lt;/p&gt;
&lt;p&gt;但当我看着 Claude Code 分分钟重构完原本我打算花一周时间重构的跨平台渲染器并跑起来时，我觉得这杠杆不存在了，连支点都不复存在了。&lt;/p&gt;
&lt;h2 id=&quot;智力通胀&quot;&gt;&lt;a href=&quot;#智力通胀&quot; class=&quot;headerlink&quot; title=&quot;智力通胀&quot;&gt;&lt;/a&gt;智力通胀&lt;/h2&gt;&lt;p&gt;过去，智力水平可以看作是一种壁垒，绝顶聪明的人万里挑一。但在 AI 浪潮下智力正在发生严重的通货膨胀。智力变成了水电煤一样的基础商品，只要肯付钱买， Token 就能无限供应。我们这些”脑力劳动者”的底层价值正在迅速瓦解。&lt;/p&gt;
&lt;p&gt;我逐渐意识到，Token 根本不是什么 LLM 的输出单位。它是&lt;strong&gt;全新的生产资料&lt;/strong&gt;，是 AI 时代的”石油”。谁掌握了它，谁就拥有了新质生产力。&lt;/p&gt;
&lt;h2 id=&quot;Tokenmaxxing：硅谷的新风尚&quot;&gt;&lt;a href=&quot;#Tokenmaxxing：硅谷的新风尚&quot; class=&quot;headerlink&quot; title=&quot;Tokenmaxxing：硅谷的新风尚&quot;&gt;&lt;/a&gt;Tokenmaxxing：硅谷的新风尚&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;/images/tokenmaxxing.webp&quot; alt=&quot;Tokenmaxxing&quot;&gt;&lt;br&gt;&lt;em&gt;Tokenmaxxing 游戏：把 AI 额度用到极限。图来自digit.in&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;你也许刷到过，硅谷的科技公司正掀起一场刷 Token 的比赛，叫 &lt;strong&gt;Tokenmaxxing&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在 Meta 和 OpenAI 的内部，现在赫然矗立着「Token 消耗排行榜」，不比做出什么东西，纯粹看烧了多少 Token——比谁在同一时间周期内更会烧 Token！&lt;a href=&quot;https://www.zhihu.com/question/2017627475413262735&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;阿里和腾讯也宣称为员工提供无限量免费 Token 福利&lt;/a&gt;，鼓励使用 AI 工具工作。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/are-you-tokenmaxxing.png&quot; alt=&quot;Are You Tokenmaxxing?&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="扯淡" scheme="https://yrom.net/categories/%E6%89%AF%E6%B7%A1/"/>
    
    
      <category term="AI" scheme="https://yrom.net/tags/AI/"/>
    
      <category term="思考" scheme="https://yrom.net/tags/%E6%80%9D%E8%80%83/"/>
    
      <category term="Token" scheme="https://yrom.net/tags/Token/"/>
    
      <category term="程序员" scheme="https://yrom.net/tags/%E7%A8%8B%E5%BA%8F%E5%91%98/"/>
    
  </entry>
  
  <entry>
    <title>没有银弹：Agentic Coding 时代的软件工程效率边界</title>
    <link href="https://yrom.net/blog/2026/03/16/is-agentic-coding-a-silver-bullet/"/>
    <id>https://yrom.net/blog/2026/03/16/is-agentic-coding-a-silver-bullet/</id>
    <published>2026-03-16T15:10:00.000Z</published>
    <updated>2026-04-21T15:36:53.468Z</updated>
    
    <summary type="html">
    
      &lt;!-- # 没有银弹：Agentic Coding 时代的软件工程效率边界 --&gt;

&lt;blockquote&gt;
&lt;p&gt; Fred Brooks 在 1986 年关于《没有银弹》的预言，在 2026 年 AI Coding 火热的当下依然成立吗？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;1-Fred-Brooks-的框架：本质-vs-偶然&quot;&gt;&lt;a href=&quot;#1-Fred-Brooks-的框架：本质-vs-偶然&quot; class=&quot;headerlink&quot; title=&quot;1. Fred Brooks 的框架：本质 vs 偶然&quot;&gt;&lt;/a&gt;1. Fred Brooks 的框架：本质 vs 偶然&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;/images/no-silver-bullet-frederick-brooks.png&quot; alt=&quot;Fred Brooks 与《没有银弹》论文&quot;&gt;&lt;br&gt;1986 年，《人月神话》的作者 &lt;a href=&quot;https://en.wikipedia.org/wiki/Fred_Brooks&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Fred Brooks&lt;/a&gt; 发表了一篇经典&lt;a href=&quot;https://www.cs.unc.edu/techreports/86-020.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;论文&lt;/a&gt; &lt;em&gt;《No Silver Bullet - Essence and Accidents of Software Engineering》&lt;/em&gt; ，他借用亚里士多德哲学概念把当时的软件工程的面临的困难分成了两类：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;定义&lt;/th&gt;
&lt;th&gt;能否消除&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Essence（本质）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;软件固有的内在的、不可简化的属性，完全靠人抽象的逻辑思维活动进行概念构建、系统设计&lt;/td&gt;
&lt;td&gt;❌ 无法消除&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accidents（偶然）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;抽象概念的表达（编码）过程中，工具、实践、环境带来的伴生问题，比如受制于硬件、编程语言特性、研发团队的协作等&lt;/td&gt;
&lt;td&gt;✅ 可以改进&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;1-1-四大本质困难&quot;&gt;&lt;a href=&quot;#1-1-四大本质困难&quot; class=&quot;headerlink&quot; title=&quot;1.1 四大本质困难&quot;&gt;&lt;/a&gt;1.1 四大本质困难&lt;/h3&gt;&lt;p&gt;Brooks 进一步将本质困难分为了四大类：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Complexity（复杂性）&lt;/strong&gt;：软件系统的构造之复杂且增长非线性，导致系统的理解、设计、实现、维护等活动变得困难。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conformity（一致性）&lt;/strong&gt;：软件的复杂性很多时候是人为强加的，它必须适应各种已经存在的不同的人不同时间为不同原因建立的接口、系统、合规性约束等，没有“放之四海皆准”的解决方案。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Changeability（易变性）&lt;/strong&gt;：软件纯粹是“思想的产物”，逻辑上极易被修改，永远处于“拥抱变化”的巨大压力状态，用户不断有新需求，而软件也不断适应新硬件环境，而修改成本随系统规模增长&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invisibility（不可见性）&lt;/strong&gt;：软件无法在物理空间直接可视化她的逻辑实体，摸不到它的”几何形状”，虽然可以画流程图、架构图来描述系统的控制流、数据流等，但这些都是”静态”的描述，无法直观软件的“动态”行为，阻碍了设计者之间的沟通。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;1-2-Brooks-悲观的预言：本质困难无法消除&quot;&gt;&lt;a href=&quot;#1-2-Brooks-悲观的预言：本质困难无法消除&quot; class=&quot;headerlink&quot; title=&quot;1.2 Brooks 悲观的预言：本质困难无法消除&quot;&gt;&lt;/a&gt;1.2 Brooks 悲观的预言：本质困难无法消除&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;“&lt;em&gt;There is no single development, in either technology or management technique, which by itself promises even one order-of-magnitude improvement within a decade in productivity, in reliability, in simplicity.&lt;/em&gt;”&lt;/p&gt;
&lt;p&gt;没有任何单一的技术或管理方法，能在十年内带来哪怕一个数量级（10x）的效率提升。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如今，40 年过去了，软件工程的世界天翻地覆， AI Coding 火热的当下，这个论断还成立吗？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/software-development-life-cycle.png&quot; alt=&quot;software-development-life-cycle&quot;&gt;&lt;br&gt;&lt;em&gt;软件开发生命周期从传统到AI迁移图。图来自 &lt;a href=&quot;https://resources.anthropic.com/hubfs/2026%20Agentic%20Coding%20Trends%20Report.pdf?hsLang=en&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;《2026 Agentic Coding 趋势报告》by Anthropic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="AI" scheme="https://yrom.net/categories/AI/"/>
    
    
      <category term="AI" scheme="https://yrom.net/tags/AI/"/>
    
      <category term="软件工程" scheme="https://yrom.net/tags/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/"/>
    
      <category term="Agentic Coding" scheme="https://yrom.net/tags/Agentic-Coding/"/>
    
      <category term="SWE-bench" scheme="https://yrom.net/tags/SWE-bench/"/>
    
  </entry>
  
  <entry>
    <title>论文分享：挂羊头卖狗肉！中转站 API 的模型欺诈行为研究</title>
    <link href="https://yrom.net/blog/2026/03/06/paper-reading-shadow-api/"/>
    <id>https://yrom.net/blog/2026/03/06/paper-reading-shadow-api/</id>
    <published>2026-03-06T11:00:00.000Z</published>
    <updated>2026-03-08T15:13:35.402Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;/ai-translated-papers/2603.01919/report_figures/intro.png&quot; alt=&quot;模型欺诈&quot;&gt;&lt;br&gt;&lt;em&gt;图来自原文，Comic for the production, transaction, use, and audit of shadow APIs&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;三句话总结-TL-DR&quot;&gt;&lt;a href=&quot;#三句话总结-TL-DR&quot; class=&quot;headerlink&quot; title=&quot;三句话总结 (TL;DR)&quot;&gt;&lt;/a&gt;三句话总结 (TL;DR)&lt;/h2&gt;&lt;p&gt;想要用上GPT、Gemini、Claude 这类前沿LLM，官方API往往价格不菲、支付门槛高、还有地域限制。CISPA 信息安全中心的研究者对官方LLM API和对应的影子API进行了系统性审计，发现 &lt;strong&gt;45.83% 的Endpoint无法通过模型指纹验证&lt;/strong&gt;，有些甚至还是开源模型平替或者降智版，与官方API的跑分性能差异最高达 &lt;strong&gt;47.21%&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;CISPA Helmholtz Center for Information Security 是德国顶尖的网络安全研究机构&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你以为掏钱买的 GPT-5，但实际中转站可能给你用的是 GLM-4-9B！&lt;/p&gt;
&lt;p&gt;更令人瞠目的是研究者发现有多个影子API被上百篇学术论文使用过，其中最火的一个（论文作者没提是哪篇），截至2025年12月6日，引用量高达近6千次，在GitHub上收获了58k stars，这意味着部分学术结论建立在错误的基础上！严重损害了科学研究的可重复性和有效性。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Most of these papers have accepted by top venues, such as ACL, CVPR, and ICLR…&lt;br&gt;These deceptive practices critically undermine the reproducibility and validity of scientific research…&lt;/p&gt;
&lt;/blockquote&gt;
    
    </summary>
    
      <category term="AI" scheme="https://yrom.net/categories/AI/"/>
    
    
      <category term="LLM" scheme="https://yrom.net/tags/LLM/"/>
    
      <category term="API安全" scheme="https://yrom.net/tags/API%E5%AE%89%E5%85%A8/"/>
    
      <category term="模型验证" scheme="https://yrom.net/tags/%E6%A8%A1%E5%9E%8B%E9%AA%8C%E8%AF%81/"/>
    
  </entry>
  
  <entry>
    <title>Pass^k：评估智能体可靠性的建议指标</title>
    <link href="https://yrom.net/blog/2026/03/03/pass%5Ek-for-eval-agents/"/>
    <id>https://yrom.net/blog/2026/03/03/pass^k-for-eval-agents/</id>
    <published>2026-03-03T10:30:00.000Z</published>
    <updated>2026-03-03T13:34:31.501Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;Google DeepMind 的研究员 &lt;a href=&quot;https://www.philschmid.de/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Philipp Schmid&lt;/a&gt; 指出，业界常用的评估指标 &lt;code&gt;Pass@k&lt;/code&gt; 具有一定的迷惑性和误导性，建议使用&lt;code&gt;Pass^k&lt;/code&gt; 来评估智能体的可靠性。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/the-difference-bettween-pass@k-and-pass%5Ek.png&quot; alt=&quot;the-difference-bettween-pass@k-and-pass^k&quot;&gt;&lt;br&gt;&lt;em&gt;图来自Anthropic 的技术博客 Demystifying evals for AI agents&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="AI" scheme="https://yrom.net/categories/AI/"/>
    
    
      <category term="AI" scheme="https://yrom.net/tags/AI/"/>
    
      <category term="Agent" scheme="https://yrom.net/tags/Agent/"/>
    
      <category term="LLM" scheme="https://yrom.net/tags/LLM/"/>
    
      <category term="eval" scheme="https://yrom.net/tags/eval/"/>
    
  </entry>
  
  <entry>
    <title>论文分享：攻破你的 OpenClaw 🦞机器人，最好用的武器是 PUA</title>
    <link href="https://yrom.net/blog/2026/03/03/paper-reading-agents-of-chaos/"/>
    <id>https://yrom.net/blog/2026/03/03/paper-reading-agents-of-chaos/</id>
    <published>2026-03-03T04:00:00.000Z</published>
    <updated>2026-03-03T13:41:36.802Z</updated>
    
    <summary type="html">
    
      30+ 位研究者给 AI 智能体配了邮箱、Discord 和 Shell 权限，然后让 20 人去攻破它们。技术攻击全被防住了，社会工程攻击全军覆没。
    
    </summary>
    
      <category term="AI" scheme="https://yrom.net/categories/AI/"/>
    
    
      <category term="Agent" scheme="https://yrom.net/tags/Agent/"/>
    
      <category term="LLM" scheme="https://yrom.net/tags/LLM/"/>
    
      <category term="AI Safety" scheme="https://yrom.net/tags/AI-Safety/"/>
    
      <category term="Red-teaming" scheme="https://yrom.net/tags/Red-teaming/"/>
    
      <category term="Multi-agent" scheme="https://yrom.net/tags/Multi-agent/"/>
    
  </entry>
  
  <entry>
    <title>论文分享：AI 如何影响技能形成</title>
    <link href="https://yrom.net/blog/2026/02/26/paper-reading-how-ai-impacts-skill-formation/"/>
    <id>https://yrom.net/blog/2026/02/26/paper-reading-how-ai-impacts-skill-formation/</id>
    <published>2026-02-26T09:20:00.000Z</published>
    <updated>2026-03-03T12:39:19.278Z</updated>
    
    <summary type="html">
    
      Anthropic 的随机对照试验证明，用 AI 辅助学新库会让测验分数掉 17%，但「只问概念不要代码」的交互模式能保住学习效果
    
    </summary>
    
      <category term="AI" scheme="https://yrom.net/categories/AI/"/>
    
    
      <category term="AI" scheme="https://yrom.net/tags/AI/"/>
    
      <category term="SKILL" scheme="https://yrom.net/tags/SKILL/"/>
    
  </entry>
  
  <entry>
    <title>【AI】论文精读：TinyLoRA —— 用 13 个参数让模型学会推理</title>
    <link href="https://yrom.net/blog/2026/02/10/paper-reading-tinylora/"/>
    <id>https://yrom.net/blog/2026/02/10/paper-reading-tinylora/</id>
    <published>2026-02-10T12:00:00.000Z</published>
    <updated>2026-03-08T15:33:59.725Z</updated>
    
    <summary type="html">
    
      &lt;div class=&quot;admonition warning&quot;&gt;&lt;p class=&quot;admonition-title&quot;&gt;注意
&lt;/p&gt;&lt;p&gt;这是一篇让AI总结的论文精读，我只做了简单的修正和补充。可能存在错误或不准确的地方。&lt;/p&gt;
&lt;/div&gt;

&lt;!-- # 【AI】论文精读：TinyLoRA —— 用 13 个参数让模型学会推理 --&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;论文&lt;/strong&gt;：Learning to Reason in 13 Parameters&lt;br&gt;&lt;strong&gt;arXiv&lt;/strong&gt;：&lt;a href=&quot;https://arxiv.org/abs/2602.04118&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2602.04118&lt;/a&gt;&lt;br&gt;&lt;strong&gt;主题&lt;/strong&gt;：参数高效微调（PEFT）与强化学习（RL）&lt;br&gt;&lt;img src=&quot;/images/screenshot-learning-to-reason-in-13-parameters.png&quot; alt=&quot;screenshot&quot;&gt;&lt;br&gt;中文翻译版：&lt;a href=&quot;/ai-translated-papers/2602.04118/用13个参数学习推理-arxiv-2602.04118.pdf&quot;&gt;2602.04118&lt;/a&gt;&lt;br&gt;翻译SKILL: &lt;a href=&quot;https://github.com/yrom/arxiv-paper-translator&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;yrom/arxiv-paper-translator&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;一句话总结（TL-DR）&quot;&gt;&lt;a href=&quot;#一句话总结（TL-DR）&quot; class=&quot;headerlink&quot; title=&quot;一句话总结（TL;DR）&quot;&gt;&lt;/a&gt;一句话总结（TL;DR）&lt;/h2&gt;&lt;p&gt;TinyLoRA 用 LoRA-XS + 随机投影 + 权重绑定把可训练参数压到 13 个，配合 GRPO 在 GSM8K 评测集上跑分从 76% 提到 91%。关键发现：强化学习（RL） 的稀疏可验证信号比监督微调（SFT）的逐 Token 信号更适合采用极低参数的设置。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;1-直觉开场：13-个参数？&quot;&gt;&lt;a href=&quot;#1-直觉开场：13-个参数？&quot; class=&quot;headerlink&quot; title=&quot;1. 直觉开场：13 个参数？&quot;&gt;&lt;/a&gt;1. 直觉开场：13 个参数？&lt;/h2&gt;&lt;p&gt;如果把全量微调看成”重装整台电脑”，那 LoRA 像”换一条内存条”，TinyLoRA 则更像”在 BIOS 里拨了 13 个开关”——改动极小，但让模型更愿意”想一想、写长一点”，推理准确率就上来了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/ai-translated-papers/2602.04118/report_figures/1_main_grpo.png&quot; alt=&quot;图1：GSM8K 上 TinyLoRA + GRPO 在 13 参数下接近全量微调&quot;&gt;&lt;br&gt;&lt;em&gt;图1：GSM8K 主结果（GRPO）。13 参数即可逼近全量微调性能，虚线为未训练与全量微调基线。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/ai-translated-papers/2602.04118/report_figures/1_main_sft.png&quot; alt=&quot;图2：SFT 在 GSM8K 上需要更大的更新规模&quot;&gt;&lt;br&gt;&lt;em&gt;图2：SFT 在低参数区间效果明显弱于 RL，达到相近性能需要更大的更新规模。&lt;/em&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="Machine Learning" scheme="https://yrom.net/categories/Machine-Learning/"/>
    
    
      <category term="LLM" scheme="https://yrom.net/tags/LLM/"/>
    
      <category term="LoRA" scheme="https://yrom.net/tags/LoRA/"/>
    
      <category term="TinyLoRA" scheme="https://yrom.net/tags/TinyLoRA/"/>
    
      <category term="RL" scheme="https://yrom.net/tags/RL/"/>
    
  </entry>
  
  <entry>
    <title>我做了个 Skill，把论文翻译变成了一行指令</title>
    <link href="https://yrom.net/blog/2026/02/05/i-create-an-agent-skills-to-translate-arxiv-paper/"/>
    <id>https://yrom.net/blog/2026/02/05/i-create-an-agent-skills-to-translate-arxiv-paper/</id>
    <published>2026-02-05T13:00:00.000Z</published>
    <updated>2026-03-03T12:29:27.225Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;之前我用过 &lt;a href=&quot;https://github.com/PDFMathTranslate/PDFMathTranslate&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PDFMathTranslate&lt;/a&gt; 翻译 PDF 论文，效果还行。但他有个问题：&lt;strong&gt;只能翻译 PDF 文件&lt;/strong&gt;、只能按页翻译，而且很慢~。其实有时候我只需要翻译部分章节。&lt;/p&gt;
&lt;p&gt;无意间，我看到 arXiv 其实提供了PDF的 LaTeX 源码。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/screenshot-TeX_Source.png&quot; alt=&quot;arXiv 论文的 LaTeX 源码&quot;&gt;&lt;/p&gt;
&lt;p&gt;下载一个来解压看，是作者的原始LaTeX。我就想，能不能用Claude Code（或者Opencode）这种AI助手直接翻译 LaTeX 源码？然后编译出中文 PDF 文件！&lt;/p&gt;
&lt;div class=&quot;admonition note&quot;&gt;&lt;p class=&quot;admonition-title&quot;&gt;燃烧吧，GLM 4.7. 
&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/images/screenshot-glm4.7-usage.png&quot; alt=&quot;GLM Coding Plan 的用量&quot;&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;是的，我入了&lt;a href=&quot;https://www.bigmodel.cn/glm-coding?ic=B0HTDGSAES&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;GLM 的Coding Plan&lt;/a&gt; 的坑，实际体验下来，GLM 4.7 写代码只能说&lt;em&gt;凑合&lt;/em&gt;。花钱雇了一个实习生，虽然智力水平够不上博士，平常放着不用就浑身难受，我试了让他翻译翻译论文还是可以的~（虽然，需要花点时间调教&lt;/p&gt;
&lt;p&gt;这就是我搞这个项目最初的想法： &lt;a href=&quot;https://github.com/yrom/arxiv-paper-translator&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;arxiv-paper-translator&lt;/a&gt; &lt;/p&gt;
    
    </summary>
    
      <category term="AI" scheme="https://yrom.net/categories/AI/"/>
    
    
      <category term="Agent" scheme="https://yrom.net/tags/Agent/"/>
    
      <category term="Skills" scheme="https://yrom.net/tags/Skills/"/>
    
  </entry>
  
  <entry>
    <title>Develop OpenGL Apps In A Docker Container Without GPU</title>
    <link href="https://yrom.net/blog/2025/07/27/develop-opengl-apps-in-docker-without-gpu/"/>
    <id>https://yrom.net/blog/2025/07/27/develop-opengl-apps-in-docker-without-gpu/</id>
    <published>2025-07-27T13:00:00.000Z</published>
    <updated>2026-03-03T12:29:27.224Z</updated>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Introduction&quot;&gt;&lt;a href=&quot;#Introduction&quot; class=&quot;headerlink&quot; title=&quot;Introduction&quot;&gt;&lt;/a&gt;Introduction&lt;/h2&gt;&lt;p&gt;When developing graphics applications such as OpenGL or Vulkan apps, we typically using hardware acceleration need a graphics card (Graphics Processing Unit, aka. GPU) to render graphics for better performance and visual quality.&lt;/p&gt;
&lt;p&gt;However, in some cases, we may not have access to a GPU, such as headless cloud server or in a CI/CD environment.&lt;/p&gt;
&lt;p&gt;In this blog post, I will show you how to develop OpenGL applications inside a Linux server environment which is running in a GPU-less Docker container (in my case, a MacBook Pro with Apple Silicon M3).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Github repo &lt;a href=&quot;https://github.com/yrom/docker-egl-opengl&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;yrom/docker-egl-opengl&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;Overview&quot;&gt;&lt;a href=&quot;#Overview&quot; class=&quot;headerlink&quot; title=&quot;Overview&quot;&gt;&lt;/a&gt;Overview&lt;/h2&gt;&lt;p&gt;On a headless Linux server without a GPU, we can use the software implementation of OpenGL provided by &lt;a href=&quot;https://docs.mesa3d.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Mesa&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;admonition note&quot;&gt;&lt;p class=&quot;admonition-title&quot;&gt;About Mesa
&lt;/p&gt;&lt;p&gt;Mesa is an open-source implementation of OpenGL that provides software rasterizers inside its &lt;a href=&quot;https://docs.mesa3d.org/gallium/intro.html#what-is-gallium&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gallium&lt;/a&gt; driver, such as &lt;code&gt;softpipe&lt;/code&gt; and &lt;code&gt;LLVMpipe&lt;/code&gt;, for CPU-based rendering. &lt;br&gt;
The Gallium &lt;code&gt;LLVMpipe&lt;/code&gt; driver uses &lt;a href=&quot;https://llvm.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LLVM&lt;/a&gt; to do runtime code generation with LLVM IR, is multithreaded and offers better performance than &lt;code&gt;softpipe&lt;/code&gt;.&lt;br&gt;
Read more about &lt;a href=&quot;https://docs.mesa3d.org/drivers/llvmpipe.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Mesa&#39;s llvmpipe&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;On Linux, &lt;a href=&quot;https://www.khronos.org/egl/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;EGL&lt;/a&gt; is commonly used as the integration layer between OpenGL and the native windowing system, such as &lt;em&gt;X window system&lt;/em&gt; and &lt;a href=&quot;https://www.reddit.com/r/linux/comments/1h1347g/what_advantages_does_wayland_has_for_the_user/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;em&gt;Wayland&lt;/em&gt;&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;EGL also supports off-screen rendering by creating an headless surface called Pbuffer (pixel buffer), which  enables rendering without any real display or window.&lt;/p&gt;
&lt;div style=&quot;text-align:center;&quot;&gt;
&lt;object type=&quot;image/svg+xml&quot; data=&quot;/blog/assets/egl-opengl-rtt.svg&quot; style=&quot;width:35%&quot;&gt;&lt;/object&gt;&lt;br&gt;
RTT (Render To Texture) with EGL + OpenGL &lt;br&gt;&lt;i style=&quot;font-size:smaller; color:grey;&quot;&gt;Image made by author&lt;/i&gt;
&lt;/div&gt;
    
    </summary>
    
      <category term="Graphics" scheme="https://yrom.net/categories/Graphics/"/>
    
    
      <category term="Graphics" scheme="https://yrom.net/tags/Graphics/"/>
    
      <category term="OpenGL" scheme="https://yrom.net/tags/OpenGL/"/>
    
      <category term="Docker" scheme="https://yrom.net/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>微调IndexTTS以输出可控情绪的语言音频</title>
    <link href="https://yrom.net/blog/2025/06/15/finetune-indextts-to-generate-controllable-emotions-speech/"/>
    <id>https://yrom.net/blog/2025/06/15/finetune-indextts-to-generate-controllable-emotions-speech/</id>
    <published>2025-06-15T12:12:20.000Z</published>
    <updated>2026-03-03T13:09:28.290Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;本文为作者记录学习和微调 IndexTTS 以生成带有可控情绪的语音音频的过程。&lt;/p&gt;
&lt;div class=&quot;admonition note&quot;&gt;&lt;p class=&quot;admonition-title&quot;&gt; About IndexTTS
&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/index-tts/index-tts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;IndexTTS&lt;/a&gt; &lt;a href=&quot;https://arxiv.org/abs/2502.05512&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;img src=&quot;https://img.shields.io/badge/ArXiv-2502.05512-red&quot; alt=&quot;arXiv:2502.05512&quot;&gt;&lt;/a&gt; 是B站 Index 团队开源的一款语音合成模型TTS，支持中文、英文的零样本语音克隆。特色是参数量小还可以用拼音声调来控制中文多音字发音。其基本结构基于 &lt;a href=&quot;https://github.com/neonbjb/tortoise-tts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Tortoise TTS&lt;/a&gt; 和 &lt;a href=&quot;https://github.com/coqui-ai/TTS/blob/dev/TTS/tts/models/xtts.py&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;XTTS&lt;/a&gt;，声码器（Vocoder） 则采用 &lt;a href=&quot;https://github.com/NVIDIA/BigVGAN&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;BigVGAN&lt;/a&gt;。虽然&lt;a href=&quot;https://index-tts.github.io/#section6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;官方报告&lt;/a&gt;中提到了支持合成&lt;code&gt;可控&lt;/code&gt;情绪音频，但实际目前并未开放相关能力的代码和使用方式 &lt;a href=&quot;https://github.com/index-tts/index-tts/issues/13&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;issues#13&lt;/a&gt;。&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;微调实验结果&quot;&gt;&lt;a href=&quot;#微调实验结果&quot; class=&quot;headerlink&quot; title=&quot;微调实验结果&quot;&gt;&lt;/a&gt;微调实验结果&lt;/h2&gt;&lt;p&gt;以下使用 NVIDIA GeForce RTX 4070 大约半小时微调后的 IndexTTS 所生成的中英文语音音频样例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参考音频&lt;/th&gt;
&lt;th&gt;合成的语音试听&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/blog/assets/Elise-1.wav&quot;&gt;Elise-1&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Hey there my name is Elise, &amp;lt;GIGGLES&amp;gt; and I’m a speech generation model that can sound like a person. &lt;br&gt; &lt;audio controls&gt;&lt;source src=&quot;/blog/assets/Elise-1_HeytheremynameisEliseGIGGLESandIm.wav&quot; type=&quot;audio/x-wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;audio controls&gt;&lt;source src=&quot;/blog/assets/Elise-1.wav&quot; type=&quot;audio/x-wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;td&gt;你 好 , 我 是 ELISE, 一 个 语 音 生 成 模 型 , &amp;lt;GIGGLES&amp;gt; 我 的 声 音 听 起 来 跟 真 人 一 样 . &lt;br&gt;  &lt;audio controls&gt;&lt;source src=&quot;/blog/assets/Elise-1_%E4%BD%A0%E5%A5%BD%E6%88%91%E6%98%AFELISE%E4%B8%80%E4%B8%AA%E8%AF%AD%E9%9F%B3%E7%94%9F%E6%88%90%E6%A8%A1%E5%9E%8BGIGGLES.wav&quot; type=&quot;audio/x-wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/blog/assets/4813840990459345930.wav&quot;&gt;Female-1&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Seriously? &amp;lt;giggles&amp;gt; That’s the cutest thing I’ve ever heard! &lt;br&gt;  &lt;audio controls&gt;&lt;source src=&quot;/blog/assets/Female-1_SeriouslygigglesThatsthecutestt.wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;audio controls&gt;&lt;source src=&quot;/blog/assets/4813840990459345930.wav&quot; type=&quot;audio/x-wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;td&gt;真的吗？ &amp;lt;giggles&amp;gt; 这也太可爱了吧！ &lt;br&gt;   &lt;audio controls&gt;&lt;source src=&quot;/blog/assets/Female-1_%E7%9C%9F%E7%9A%84%E5%90%97giggles%E8%BF%99%E4%B9%9F%E5%A4%AA%E5%8F%AF%E7%88%B1%E4%BA%86%E5%90%A7.wav&quot; type=&quot;audio/x-wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://bytedancespeech.github.io/seedtts_tech_report/audios/SpeechFactorization_samples/source/2188769758301752050.wav&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Male-1&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Wha—? Cute? &amp;lt;giggles&amp;gt; You think I’m cute?! Well, uh, thanks, I guess? &lt;br&gt;   &lt;audio controls&gt;&lt;source src=&quot;/blog/assets/Male-1_Wha—CutegigglesYouthinkImcute.wav&quot; type=&quot;audio/x-wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;audio controls&gt;&lt;source src=&quot;/blog/assets/2188769758301752050.wav&quot; type=&quot;audio/x-wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;td&gt;哎呀! 忘了他还在那等我们呢！ &amp;lt;giggles&amp;gt; 我们两个动作得快点了！ &lt;br&gt;  &lt;audio controls&gt;&lt;source src=&quot;/blog/assets/Male-1_%E5%93%8E%E5%91%80%E5%BF%98%E4%BA%86%E4%BB%96%E8%BF%98%E5%9C%A8%E9%82%A3%E7%AD%89%E6%88%91%E4%BB%AC%E5%91%A2giggles%E6%88%91%E4%BB%AC%E4%B8%A4%E4%B8%AA%E5%8A%A8%E4%BD%9C%E5%BE%97%E5%BF%AB%E7%82%B9%E4%BA%86.wav&quot; type=&quot;audio/x-wav&quot;&gt; &lt;/audio&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;完整的实验 Jupyter Notebook 见仓库 &lt;a href=&quot;https://github.com/yrom/finetune-index-tts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;yrom/finetune-index-tts&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;模型结构与微调思路&quot;&gt;&lt;a href=&quot;#模型结构与微调思路&quot; class=&quot;headerlink&quot; title=&quot;模型结构与微调思路&quot;&gt;&lt;/a&gt;模型结构与微调思路&lt;/h2&gt;&lt;p&gt;IndexTTS 基于 &lt;a href=&quot;https://github.com/neonbjb/tortoise-tts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Tortoise TTS&lt;/a&gt;，采用了多个模块协同，其主要流程如下：&lt;/p&gt;
&lt;div style=&quot;text-align:center;&quot;&gt;
&lt;object type=&quot;image/svg+xml&quot; data=&quot;https://mermaid.ink/svg/pako:eNpNU01v2kAQ_SurPRnLIPONfahkbIQqBWQVRKXiHFx7Aatgo8W0TQApaSsRpQfIJZVSoiaohxzackgVRbT5N2DgX3TNAsWX9byZffPm7W4HGo6JoAgrdeedUdOxC4qKZgPyKYwG54MPy5OP3mXfG_3QYAAEg8_SaqZcZlmysOzhoY-AIkMrQNF5g2zwXAlQBmnHsJz8XH273zCAHJND9WChiQwXO1WsNyhcknxmxWoZGLmIRITfx9O7crD4e7m4Od3r4G-U_W2yY1cc3EAYZGx_JLwVpyKSVRE2kPWWZF-glt5o1v_nZYnZ1zh7PJ89fibzzIcXq_5gray7A73r29mfhy6Qafs0ZaBBkQa-OVm1GPHdoQl5nTggZiy-_vJu-rTR4uqT9zSaj-6Wt3eL71NNs9nV1XD5ZbA4f_BOTlliFt1-QM0plzXIpq1qKSvlWVLNZJGNsO46OKDBbau1H6CgEhEZWVKlYFHJ5zc2Fpjl5Pdycj2bTkGm8RqZpmVXNz0KtAcNSuuZ58Mz72zYBaqcI8qJ4NX4wrsfz5_GgCFYYHuYL0mWTkRrCA45SA6ioVsmuVgdn1SDbg01kAZF8muiit6uuxrU7B4p1duuUziyDSi6uI04iJ12tQbFil5vkajdNHUXKZbu35NtSVO3XznOfgjFDnwPxWA4lIjEEuFIMpzgeV4Ihzl4RGA-FIsnUrGYkIrG-GhS4BPxHgeP1xx8SIin4nw8xQtRPskLqRgHkWkRY3P0aaxfCAer2J9noxHZ5IrJTtt2oSj0_gHeei46&quot;&gt;&lt;/object&gt;
&lt;span style=&quot;font-size:smaller; color:grey&quot;&gt;图为作者绘制&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;要达到微调目标，主要涉及两个核心部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;BPE 分词器&lt;/strong&gt;: 基于 &lt;a href=&quot;https://github.com/google/sentencepiece&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;sentencepiece&lt;/a&gt;，将文本和新增的情绪标签（如 &lt;code&gt;&amp;lt;GIGGLES&amp;gt;&lt;/code&gt;）编码为词表序列ID。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT2 自回归模块&lt;/strong&gt;：通过微调学习根据目标情绪标签ID生成合适的音频 latent 表示。&lt;/li&gt;
&lt;/ul&gt;
    
    </summary>
    
      <category term="Machine Learning" scheme="https://yrom.net/categories/Machine-Learning/"/>
    
    
      <category term="LLM" scheme="https://yrom.net/tags/LLM/"/>
    
      <category term="LoRA" scheme="https://yrom.net/tags/LoRA/"/>
    
      <category term="FineTune" scheme="https://yrom.net/tags/FineTune/"/>
    
      <category term="IndexTTS" scheme="https://yrom.net/tags/IndexTTS/"/>
    
      <category term="GPT2" scheme="https://yrom.net/tags/GPT2/"/>
    
  </entry>
  
  <entry>
    <title>将PyTorch模型适配到MLX</title>
    <link href="https://yrom.net/blog/2025/05/14/adapt-a-pytorch-model-to-mlx/"/>
    <id>https://yrom.net/blog/2025/05/14/adapt-a-pytorch-model-to-mlx/</id>
    <published>2025-05-14T06:12:10.000Z</published>
    <updated>2026-03-03T13:05:28.843Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;本文记录一下将&lt;code&gt;PyTorch&lt;/code&gt;模型适配到&lt;code&gt;MLX&lt;/code&gt;的过程。&lt;/p&gt;
&lt;h2 id=&quot;什么是MLX？&quot;&gt;&lt;a href=&quot;#什么是MLX？&quot; class=&quot;headerlink&quot; title=&quot;什么是MLX？&quot;&gt;&lt;/a&gt;什么是MLX？&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;MLX is an array framework for machine learning on Apple silicon, brought to you by Apple machine learning research.&lt;br&gt;&lt;a href=&quot;https://github.com/ml-explore/mlx/blob/main/README.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/ml-explore/mlx/blob/main/README.md&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ml-explore/mlx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MLX&lt;/a&gt; 是适应于苹果M系列芯片(Apple Silicon)的机器学习框架。&lt;/p&gt;
&lt;p&gt;mlx的&lt;code&gt;array&lt;/code&gt;设计更加接近于&lt;code&gt;numpy&lt;/code&gt;&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; rel=&quot;footnote&quot;&gt;&lt;span class=&quot;hint--top hint--error hint--medium hint--rounded hint--bounce&quot; aria-label=&quot;[numpy](https://numpy.org/) NumPy is the fundamental package for scientific computing in Python.
&quot;&gt;[1]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;，而不是PyTorch的&lt;code&gt;tensor&lt;/code&gt;，即只存有结构信息（如形状、数据类型等），没有其它与深度学习训练相关的属性（如梯度）。与&lt;code&gt;numpy&lt;/code&gt;和&lt;code&gt;torch&lt;/code&gt;不同的是，mlx 的&lt;code&gt;array&lt;/code&gt;是 &lt;a href=&quot;https://ml-explore.github.io/mlx/build/html/usage/unified_memory.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Unified Memory&lt;/a&gt; 可以在CPU和GPU之间共享，这也是&lt;code&gt;mlx&lt;/code&gt;被单独开发而非拓展pytorch的 &lt;a href=&quot;https://docs.pytorch.org/docs/stable/notes/mps.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;mps backend&lt;/a&gt;的理由&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; rel=&quot;footnote&quot;&gt;&lt;span class=&quot;hint--top hint--error hint--medium hint--rounded hint--bounce&quot; aria-label=&quot;[awni&#39;s answer to _Why not implement this in Pytorch?_](https://github.com/ml-explore/mlx/issues/12#issuecomment-1843956313)
&quot;&gt;[2]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;div class=&quot;admonition note&quot;&gt;&lt;p class=&quot;admonition-title&quot;&gt;array与tensor的区别
&lt;/p&gt;&lt;p&gt;&lt;code&gt;np.array&lt;/code&gt;和&lt;code&gt;torch.tensor&lt;/code&gt;的区别可以阅读&lt;a href=&quot;https://mlabonne.github.io/blog/posts/2022-03-28-What_is_a_Tensor_in_Deep_Learning.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;What is a Tensor in Machine Learning?&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;模型转换实践&quot;&gt;&lt;a href=&quot;#模型转换实践&quot; class=&quot;headerlink&quot; title=&quot;模型转换实践&quot;&gt;&lt;/a&gt;模型转换实践&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/NVIDIA/BigVGAN&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;BigVGAN&lt;/a&gt; PyTorch -&amp;gt; &lt;a href=&quot;https://github.com/yrom/mlx-bigvgan&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;mlx-BigVGAN&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;基本的映射&quot;&gt;&lt;a href=&quot;#基本的映射&quot; class=&quot;headerlink&quot; title=&quot;基本的映射&quot;&gt;&lt;/a&gt;基本的映射&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;torch&lt;/th&gt;
&lt;th&gt;mlx&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;DataTypes&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.pytorch.org/docs/stable/tensors.html#data-types&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Data types&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://ml-explore.github.io/mlx/build/html/python/data_types.html#data-types&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Data Types&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NN&lt;/td&gt;
&lt;td&gt;&lt;code&gt;torch.nn.*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mlx.nn.*&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parameters/Weight/Buffer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;torch.Tensor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mlx.core.array&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ModuleList&lt;/td&gt;
&lt;td&gt;&lt;code&gt;torch.nn.ModuleList&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ModuleDict&lt;/td&gt;
&lt;td&gt;&lt;code&gt;torch.nn.ModuleDict&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dict&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transform&lt;/td&gt;
&lt;td&gt;&lt;code&gt;torch.fft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mlx.core.fft&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
    
    </summary>
    
      <category term="Machine Learning" scheme="https://yrom.net/categories/Machine-Learning/"/>
    
    
      <category term="macOS" scheme="https://yrom.net/tags/macOS/"/>
    
      <category term="mlx" scheme="https://yrom.net/tags/mlx/"/>
    
  </entry>
  
  <entry>
    <title>如何快速定位有性能问题的 Shader 和一些简单有效的优化方法</title>
    <link href="https://yrom.net/blog/2024/04/08/how-to-find-problem-shaders/"/>
    <id>https://yrom.net/blog/2024/04/08/how-to-find-problem-shaders/</id>
    <published>2024-04-08T04:03:43.000Z</published>
    <updated>2026-03-03T12:29:27.220Z</updated>
    
    <summary type="html">
    
      &lt;h2 id=&quot;问题&quot;&gt;&lt;a href=&quot;#问题&quot; class=&quot;headerlink&quot; title=&quot;问题&quot;&gt;&lt;/a&gt;问题&lt;/h2&gt;&lt;p&gt;在特效渲染的项目中，通常会有很多的实现不同功能的 Shader，比如：高斯模糊、液化、色彩校准、LUT等等。在使用特效时会遇到一些可能是 Shader 导致的性能问题，比如：渲染速度慢、实时渲染卡顿等等。这时候，就需要一个能够快速找到有性能问题的 Shader的方法，即本文。&lt;/p&gt;
&lt;h2 id=&quot;定位&quot;&gt;&lt;a href=&quot;#定位&quot; class=&quot;headerlink&quot; title=&quot;定位&quot;&gt;&lt;/a&gt;定位&lt;/h2&gt;&lt;p&gt;工欲善其事，必先利其器。&lt;/p&gt;
&lt;p&gt;首先，需要一个能够快速评估性能的工具（详见之前的汇总&lt;a href=&quot;https://yrom.net/blog/2023/09/27/graphics-api-debuggers/&quot;&gt;Graphics API Debuggers&lt;/a&gt;），挑一个适合的测试真机+测试工具 （个人使用的是 &lt;a href=&quot;https://developer.arm.com/Tools%20and%20Software/Arm%20Performance%20Studio%20for%20Mobile&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Arm Performance Studio for Mobile&lt;/a&gt; 。&lt;/p&gt;
&lt;p&gt;推荐观测的指标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FPS （对于实时渲染的项目）&lt;/li&gt;
&lt;li&gt;GPU 使用率&lt;/li&gt;
&lt;li&gt;CPU 使用率&lt;/li&gt;
&lt;li&gt;内存使用量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其次，针使用场景创建一系列基准测试用例，用于比较不同Shader实现的性能，找出瓶颈所在。&lt;/p&gt;
&lt;p&gt;对于定位 Shader 的性能问题，推荐使用以下方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;整体，用一个简单的 Shader （或什么也不做的 NULL-Shader） 替换掉所有的 Shader，观察性能变化。如果性能有明显提升，说明瓶颈问题大概率在 Shader 上。&lt;/li&gt;
&lt;li&gt;二分法定位，将 Shader 分为 AB两部分，分别测量 A + 原始Shader 和 原始Shader + B，进行性能对比，继续二分，重复对比，直到找出性能问题的 Shader。&lt;/li&gt;
&lt;/ol&gt;
    
    </summary>
    
      <category term="Performance" scheme="https://yrom.net/categories/Performance/"/>
    
    
      <category term="Graphics" scheme="https://yrom.net/tags/Graphics/"/>
    
      <category term="OpenGL" scheme="https://yrom.net/tags/OpenGL/"/>
    
      <category term="Shader" scheme="https://yrom.net/tags/Shader/"/>
    
      <category term="Performance" scheme="https://yrom.net/tags/Performance/"/>
    
  </entry>
  
  <entry>
    <title>OpenGL Uniform Buffer Object 的坑</title>
    <link href="https://yrom.net/blog/2024/02/24/opengl-ubo-pitfalls/"/>
    <id>https://yrom.net/blog/2024/02/24/opengl-ubo-pitfalls/</id>
    <published>2024-02-24T05:10:00.000Z</published>
    <updated>2026-03-03T12:29:27.219Z</updated>
    
    <summary type="html">
    
      &lt;h2 id=&quot;什么是-Uniform-Buffer-Object？&quot;&gt;&lt;a href=&quot;#什么是-Uniform-Buffer-Object？&quot; class=&quot;headerlink&quot; title=&quot;什么是  Uniform Buffer Object？&quot;&gt;&lt;/a&gt;什么是  Uniform Buffer Object？&lt;/h2&gt;&lt;p&gt;见WIKI： &lt;a href=&quot;https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;及 learnopengl 中的示例：&lt;a href=&quot;https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL#:~:text=the%20geometry%20shader.-,Uniform%20buffer%20objects,-We%27ve%20been%20using&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL#:~:text=the%20geometry%20shader.-,Uniform%20buffer%20objects,-We%27ve%20been%20using&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在项目中使用 UBO 时，遇到了一些坑，这里记录一下。&lt;/p&gt;
&lt;h2 id=&quot;坑1：UBO-的对齐问题&quot;&gt;&lt;a href=&quot;#坑1：UBO-的对齐问题&quot; class=&quot;headerlink&quot; title=&quot;坑1：UBO 的对齐问题&quot;&gt;&lt;/a&gt;坑1：UBO 的对齐问题&lt;/h2&gt;&lt;p&gt;在使用 UBO 时，需要注意 UBO 的对齐问题。为了代码的&lt;strong&gt;可移植性&lt;/strong&gt;，一般会直接使用 &lt;code&gt;std140&lt;/code&gt; 来定义 UBO 的内存布局，如：&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;layout (std140) uniform ExampleBlock&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    float value;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    vec3  vector;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    mat4  matrix;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    bool  boolean;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://ptgmedia.pearsoncmg.com/images/9780321552624/downloads/0321552628_AppL.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;std140&lt;/code&gt; 的布局规则&lt;/a&gt; 理解了是一回事，但是在C++中写一个 UBO 对应的struct 的时候，还是会出现对齐问题。比如C++ 中用下面这个 struct 来对应上面的 &lt;code&gt;ExampleBlock&lt;/code&gt;：&lt;/p&gt;
&lt;figure class=&quot;highlight cpp&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ExampleBlock&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt; value;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    glm::vec3 &lt;span class=&quot;built_in&quot;&gt;vector&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    glm::mat4 matrix;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;bool&lt;/span&gt; boolean;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;p&gt;这个结构体在C++编译器的眼里是按&lt;a href=&quot;https://carlosvin.github.io/langs/en/posts/cpp-pragma-pack/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++ 自己的内存布局规则来的&lt;/a&gt;，这时候我们需要手动按&lt;code&gt;std140&lt;/code&gt;对齐：&lt;/p&gt;
&lt;figure class=&quot;highlight cpp&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;struct &lt;span class=&quot;title&quot;&gt;alignas&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(&lt;span class=&quot;number&quot;&gt;16&lt;/span&gt;)&lt;/span&gt; ExampleBlock &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;float&lt;/span&gt; value;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    glm::vec4 &lt;span class=&quot;built_in&quot;&gt;vector&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    glm::mat4 matrix;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    alignas(&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;) &lt;span class=&quot;keyword&quot;&gt;bool&lt;/span&gt; boolean;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;p&gt;注意上面例子中的 struct 中的 &lt;code&gt;bool&lt;/code&gt; 类型，需要对齐到 &lt;code&gt;4&lt;/code&gt;字节。&lt;/p&gt;
&lt;p&gt;但是，如果你这么写了，仍然可能会遇到一个问题，C++ 代码中明明设置的是 &lt;code&gt;false&lt;/code&gt; ，但是程序执行后，在 Shader Program 中读取到的却是 &lt;code&gt;true&lt;/code&gt;。(ﾟДﾟ≡ﾟдﾟ)!?&lt;/p&gt;
    
    </summary>
    
      <category term="Graphics" scheme="https://yrom.net/categories/Graphics/"/>
    
    
      <category term="Graphics" scheme="https://yrom.net/tags/Graphics/"/>
    
      <category term="C++" scheme="https://yrom.net/tags/C/"/>
    
      <category term="OpenGL" scheme="https://yrom.net/tags/OpenGL/"/>
    
      <category term="UBO" scheme="https://yrom.net/tags/UBO/"/>
    
  </entry>
  
  <entry>
    <title>通过 dyld-interposing 实现C/C++代码注入</title>
    <link href="https://yrom.net/blog/2023/10/19/dyld-interposing/"/>
    <id>https://yrom.net/blog/2023/10/19/dyld-interposing/</id>
    <published>2023-10-19T06:22:54.000Z</published>
    <updated>2026-03-03T12:29:27.217Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;苹果系统的链接器&lt;code&gt;/usr/lib/dyld&lt;/code&gt; 提供了一个叫&lt;code&gt;dyld-interposing&lt;/code&gt;的功能（从 Mac OS X 10.4 开始），可以在程序启动时替换掉某个函数的实现。这个功能可以用来实现代码注入（详见：&lt;a href=&quot;https://atakua.org/p/books/Mac%20OS%20X%20Internals%20-%20A%20Systems%20Approach.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;《Mac OS X Internals: A Systems Approach》&lt;/a&gt;- Amit Singh - 第二章 2.6.3.4 &lt;em&gt;dyld&lt;/em&gt; interposing）&lt;/p&gt;
&lt;h2 id=&quot;举个栗子&quot;&gt;&lt;a href=&quot;#举个栗子&quot; class=&quot;headerlink&quot; title=&quot;举个栗子&quot;&gt;&lt;/a&gt;举个栗子&lt;/h2&gt;&lt;p&gt;比如，我们可以在程序运行时，替换掉&lt;code&gt;malloc&lt;/code&gt;函数的实现：&lt;/p&gt;
&lt;figure class=&quot;highlight c&quot;&gt;&lt;figcaption&gt;&lt;span&gt;malloc_trace.c&lt;/span&gt;&lt;/figcaption&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// malloc_trace.c&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;mach-o/dyld-interposing.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;memory.h&amp;gt; // memset&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;malloc/malloc.h&amp;gt; // malloc_printf&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; *&lt;span class=&quot;title&quot;&gt;trace_malloc&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(&lt;span class=&quot;keyword&quot;&gt;size_t&lt;/span&gt; size)&lt;/span&gt; &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;char&lt;/span&gt; *p = &lt;span class=&quot;built_in&quot;&gt;malloc&lt;/span&gt;(size);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;comment&quot;&gt;// fills with &#39;#&#39;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;built_in&quot;&gt;memset&lt;/span&gt;(p, &lt;span class=&quot;string&quot;&gt;&#39;#&#39;&lt;/span&gt;, size);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  malloc_printf(&lt;span class=&quot;string&quot;&gt;&quot;malloc(%u) = %p\n&quot;&lt;/span&gt;, size, p);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; *)p;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;DYLD_INTERPOSE(trace_malloc, &lt;span class=&quot;built_in&quot;&gt;malloc&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight c&quot;&gt;&lt;figcaption&gt;&lt;span&gt;test.c&lt;/span&gt;&lt;/figcaption&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// test.c&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;meta&quot;&gt;#&lt;span class=&quot;meta-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;meta-string&quot;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;char&lt;/span&gt; *p = (&lt;span class=&quot;keyword&quot;&gt;char&lt;/span&gt;*)&lt;span class=&quot;built_in&quot;&gt;malloc&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;printf&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;malloc return %p, %s\n&quot;&lt;/span&gt;, p, p);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;free&lt;/span&gt;(p);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;$ cc -dynamiclib -o libmalloctrace.dylib malloc_trace.c -install_name libmalloctrace.dylib&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;$ cc -o test test.c&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;$ DYLD_INSERT_LIBRARIES=libmalloctrace.dylib ./test&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(1536) = 0x7febbc808200&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(32) = 0x7febbc704130&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(32) = 0x7febbc704170&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(20) = 0x7febbc705550&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(422) = 0x7febbc7055d0&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(50) = 0x7febbc7057e0&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(16) = 0x7febbc705880&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(52) = 0x7febbc705900&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(12) = 0x7febbc7059b0&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(10) = 0x7febbc705b00&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test(46555,0x11bdd3600) malloc: malloc(4096) = 0x7febbc808800&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;malloc return 0x7febbc705b00, ##########&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
    
    </summary>
    
      <category term="Cxx" scheme="https://yrom.net/categories/Cxx/"/>
    
    
      <category term="macOS" scheme="https://yrom.net/tags/macOS/"/>
    
      <category term="Cxx" scheme="https://yrom.net/tags/Cxx/"/>
    
      <category term="Debug" scheme="https://yrom.net/tags/Debug/"/>
    
      <category term="dyld" scheme="https://yrom.net/tags/dyld/"/>
    
  </entry>
  
  <entry>
    <title>Graphics API Debuggers</title>
    <link href="https://yrom.net/blog/2023/09/27/graphics-api-debuggers/"/>
    <id>https://yrom.net/blog/2023/09/27/graphics-api-debuggers/</id>
    <published>2023-09-27T09:50:57.000Z</published>
    <updated>2026-03-03T12:29:27.216Z</updated>
    
    <summary type="html">
    
      
      
        
        
          &lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/zh-cn/windows-hardware/drivers/display/using-gpuview&quot; target=&quot;_blank&quot;
        
      
    
    </summary>
    
      <category term="Graphics" scheme="https://yrom.net/categories/Graphics/"/>
    
    
      <category term="Graphics" scheme="https://yrom.net/tags/Graphics/"/>
    
  </entry>
  
  <entry>
    <title>Learning Render Graph</title>
    <link href="https://yrom.net/blog/2023/08/13/learning-render-graph/"/>
    <id>https://yrom.net/blog/2023/08/13/learning-render-graph/</id>
    <published>2023-08-13T15:27:37.000Z</published>
    <updated>2026-03-03T12:29:27.215Z</updated>
    
    <summary type="html">
    
      &lt;h2 id=&quot;什么是-Render-Graph？&quot;&gt;&lt;a href=&quot;#什么是-Render-Graph？&quot; class=&quot;headerlink&quot; title=&quot;什么是 Render Graph？&quot;&gt;&lt;/a&gt;什么是 Render Graph？&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Render Graph&lt;/strong&gt; 或者说 &lt;strong&gt;Frame graph&lt;/strong&gt; 是对复杂渲染管线的一个高度抽象，以图（Graph）的形式呈现渲染过程中的各个步骤，不同的渲染任务之间的依赖关系，以及它们对资源（如纹理、缓冲区等）的使用。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Frame graphs&lt;/strong&gt; are a design pattern for handling complex rendering pipelines, which are currently used in industry. Their usage is motivated by handling barriers, queue synchronization and memory aliasing in the background by abstracting the rendering pipeline of a frame on a higher level.&lt;br&gt; —— &lt;a href=&quot;https://github.com/gfx-rs/gfx/wiki/Frame-graphs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/gfx-rs/gfx/wiki/Frame-graphs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;解决什么问题？&quot;&gt;&lt;a href=&quot;#解决什么问题？&quot; class=&quot;headerlink&quot; title=&quot;解决什么问题？&quot;&gt;&lt;/a&gt;解决什么问题？&lt;/h2&gt;&lt;p&gt;在传统的渲染管线中，渲染过程通常被划分为多个阶段，如下图所示：&lt;br&gt;&lt;object type=&quot;image/svg+xml&quot; data=&quot;/images/opengl-render-pipeline.svg&quot;&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;这些阶段之间存在着输入和输出的依赖关系，其中&lt;strong&gt;一个阶段的输出作为下一个阶段的输入&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Render Graph 的主要思想是将渲染过程表示为一个&lt;a href=&quot;https://en.wikipedia.org/wiki/Directed_acyclic_graph&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;有向无环图（DAG）&lt;/a&gt;，其中节点表示渲染通道（Render pass），边表示依赖关系。每个渲染通道执行特定的渲染操作，可具有输入和输出资源，例如Texture、Frame Buffer和执行的 Shader/Program。例如，假设节点 A 的输出Texture是节点 B 的输入Texture，那么节点 B 就依赖于节点 A。&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;&lt;object type=&quot;image/svg+xml&quot; data=&quot;/images/render-dag.svg&quot;&gt;&lt;/object&gt;&lt;/div&gt;

&lt;p&gt;通过概括渲染流程中的依赖关系，确保渲染阶段按正确的顺序执行，并且在需要时可基于一定的同步机制（Fence、Semaphore、Resource barriers）尽可能地&lt;strong&gt;并行&lt;/strong&gt;执行渲染通道。&lt;/p&gt;
&lt;p&gt;Render Graph 的目标是为了解决大型渲染引擎里复杂渲染管线中的一些问题。如资源生命周期管理、渲染效率、渲染过程的可视化调试等等。&lt;/p&gt;
&lt;p&gt;Render Graph 不仅在游戏引擎中广泛应用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unity 3D, &lt;a href=&quot;https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@16.0/manual/render-graph-system.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The render graph system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Unreal Engine, &lt;a href=&quot;https://docs.unrealengine.com/5.2/en-US/render-dependency-graph-in-unreal-engine/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Render Dependency Graph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cocos Creator, &lt;a href=&quot;https://blog.csdn.net/weixin_44053279/article/details/131199173&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;面向数据的可定制渲染管线&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它的理念也在现代图形 API 中可窥一斑，如&lt;code&gt;Vulkan&lt;/code&gt; 的 &lt;a href=&quot;https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Render_passes&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Render Pass&lt;/a&gt;、&lt;code&gt;DirectX 12&lt;/code&gt; 的 &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/direct3d12/recording-command-lists-and-bundles&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Command List&lt;/a&gt;、&lt;code&gt;Metal&lt;/code&gt; 的 &lt;a href=&quot;https://developer.apple.com/documentation/metal/render_passes/customizing_render_pass_setup?language=objc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Render Pass&lt;/a&gt;等。&lt;/p&gt;
    
    </summary>
    
      <category term="Graphics" scheme="https://yrom.net/categories/Graphics/"/>
    
    
      <category term="Graphics" scheme="https://yrom.net/tags/Graphics/"/>
    
  </entry>
  
  <entry>
    <title>从Android 原生库 (.so) 中里挖掘一些有用的信息</title>
    <link href="https://yrom.net/blog/2023/07/25/useful-info-of-android-so/"/>
    <id>https://yrom.net/blog/2023/07/25/useful-info-of-android-so/</id>
    <published>2023-07-25T09:20:18.000Z</published>
    <updated>2026-03-03T12:29:27.214Z</updated>
    
    <summary type="html">
    
      &lt;p&gt;当一个 Android APP 需要集成别的地方来的原生库（.so）时，你可能也会跟我一样会有那么几点疑惑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个 so 用的什么 NDK 版本编译的？会不会跟项目里其它的so 冲突，尤其项目里使用&lt;a href=&quot;https://developer.android.com/ndk/guides/cpp-support?hl=zh-cn#shared_runtimes&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;共享 C++ STL&lt;/a&gt;的情况下 &lt;code&gt;ANDROID_STL=c++_shared&lt;/code&gt;，一个应用不能使用多个 C++ 运行时&lt;/li&gt;
&lt;li&gt;这个 so 目标 Android API 等级是多少？会不会大于项目的&lt;code&gt;minSdkVersion&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;这个 so 依赖（链接）其它哪些 so？这些 so 有没有都放进项目里？&lt;/li&gt;
&lt;li&gt;这个 so 有没有除了用文件哈希之外唯一编号，用来标识崩溃堆栈等？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ps. 本文假定读者有一定 Android Native 开发经验，且理解一些基本的概念。&lt;/p&gt;
&lt;h2 id=&quot;查看-so-的-NDK-版本信息&quot;&gt;&lt;a href=&quot;#查看-so-的-NDK-版本信息&quot; class=&quot;headerlink&quot; title=&quot;查看 so 的 NDK 版本信息&quot;&gt;&lt;/a&gt;查看 so 的 NDK 版本信息&lt;/h2&gt;&lt;p&gt;通过 &lt;a href=&quot;https://man7.org/linux/man-pages/man1/readelf.1.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;readelf&lt;/code&gt;&lt;/a&gt; 工具查看 Android NDK 编译出来的 so 的 &lt;a href=&quot;https://www.sco.com/developers/gabi/latest/ch4.sheader.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;Section headers&lt;/code&gt;&lt;/a&gt; 里有什么 Android 特有的玩意。&lt;/p&gt;
&lt;p&gt;ps. 可以用 &lt;code&gt;ndk-which&lt;/code&gt; 找到 NDK 中预编译好的 &lt;code&gt;readelf&lt;/code&gt;：&lt;/p&gt;
&lt;figure class=&quot;highlight sh&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;$ &lt;span class=&quot;variable&quot;&gt;$ANDROID_NDK_HOME&lt;/span&gt;/ndk-which --abi arm64-v8a readelf&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;/~/ndk/21.4.7075529/prebuilt/darwin-x86_64/bin/../../../toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-readelf&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;p&gt;定义一个名为 &lt;code&gt;readelf&lt;/code&gt; 的 alias 方便在 Terminal 中调用 &lt;code&gt;aarch64-linux-android-readelf&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight sh&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;$ &lt;span class=&quot;built_in&quot;&gt;alias&lt;/span&gt; readelf=`&lt;span class=&quot;variable&quot;&gt;$ANDROID_NDK_HOME&lt;/span&gt;/ndk-which --abi arm64-v8a readelf`&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;$ readelf -v&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;GNU readelf (GNU Binutils) 2.27.0.20170315&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;Copyright (C) 2016 Free Software Foundation, Inc.&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;...&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;p&gt;以 NDK 中带的 &lt;code&gt;libc++_shared.so&lt;/code&gt; 为例，在我本机上路径是&lt;code&gt;$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so&lt;/code&gt;：&lt;/p&gt;
&lt;figure class=&quot;highlight sh&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;$ readelf -WS &lt;span class=&quot;variable&quot;&gt;$ANDROID_NDK_HOME&lt;/span&gt;/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
    
    </summary>
    
      <category term="Android" scheme="https://yrom.net/categories/Android/"/>
    
    
      <category term="Android" scheme="https://yrom.net/tags/Android/"/>
    
      <category term="JNI" scheme="https://yrom.net/tags/JNI/"/>
    
  </entry>
  
</feed>
