mcpField
A
axiom-concurrency-profiling

axiom-concurrency-profiling

github.com/charleswiltgen开发1.2k172 次安装今天更新
代码仓库

关于 axiom-concurrency-profiling

面向 Swift 开发者的 Instruments 并发性能诊断指南,涵盖任务执行、Actor 争用、线程池耗尽与优先级反转。

主要功能

  1. 01追踪 Swift 任务与 Actor 活动
  2. 02诊断主线程阻塞
  3. 03定位 Actor 争用
  4. 04排查线程池耗尽
  5. 05检查任务优先级反转

适用场景

  1. 01排查异步操作期间的界面卡顿
  2. 02查找已排队但未运行的任务
  3. 03追踪意外串行化的 Actor 访问

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/charleswiltgen/axiom --skill axiom-concurrency-profiling

安装后在 Claude Code 中输入/axiom-concurrency-profiling确认已加载。

详细介绍

并发性能分析 — Instruments 工作流

使用 Instruments 对 Swift async/await 代码进行性能分析和优化。

适用场景

✅ 适用:

  • 异步操作期间 UI 卡顿
  • 怀疑存在 actor 争用
  • 任务已排队但未执行
  • 异步工作期间主线程被阻塞
  • 需要查看任务执行流程

❌ 不适用:

  • 问题纯属 CPU 性能问题(使用 Time Profiler)
  • 与并发无关的内存问题(使用 Allocations)
  • 尚未确认并发是瓶颈

Swift Concurrency 模板

显示内容
轨道信息
Swift Tasks任务生命周期、父子关系
Swift ActorsActor 访问、争用可视化
Thread States阻塞、运行或挂起状态
统计数据
  • Running Tasks:当前正在执行的任务
  • Alive Tasks:某一时刻存在的任务
  • Total Tasks:累计创建的任务数
颜色说明
  • 蓝色:任务正在执行
  • 红色:任务正在等待(争用)
  • 灰色:任务已挂起(等待中)

工作流 1:诊断主线程阻塞

症状:UI 冻结,主线程时间线被占满

  1. 使用 Swift Concurrency 模板进行性能分析
  2. 查看主线程 → “Swift Tasks”轨道
  3. 找到较长的蓝色条(任务正在主线程上执行)
  4. 检查是否可以将工作移出主线程

解决方案模式:

// ❌ Heavy work on MainActor
@MainActor
class ViewModel: ObservableObject {
    func process() {
        let result = heavyComputation()  // Blocks UI
        self.data = result
    }
}

// ✅ Offload heavy work
@MainActor
class ViewModel: ObservableObject {
    func process() async {
        let result = await Task.detached {
            heavyComputation()
        }.value
        self.data = result
    }
}

工作流 2:查找 Actor 争用

症状:任务意外地串行化,并行工作按顺序运行

  1. 启用“Swift Actors”工具
  2. 查找串行访问模式
  3. 红色 = 等待,蓝色 = 执行
  4. 红蓝比例较高 = 存在争用问题

解决方案模式:

// ❌ All work serialized through actor
actor DataProcessor {
    func process(_ data: Data) -> Result {
        heavyProcessing(data)  // All callers wait
    }
}

// ✅ Mark heavy work as nonisolated
actor DataProcessor {
    nonisolated func process(_ data: Data) -> Result {
        heavyProcessing(data)  // Runs in parallel
    }

    func storeResult(_ result: Result) {
        // Only actor state access serialized
    }
}

更多修复方法:

  • 将一个 actor 拆分为多个(按领域分离)
  • 对热点路径使用 Mutex(比 actor 跳转更快)
  • 缩小 actor 的作用范围(减少隔离属性)

工作流 3:线程池耗尽

症状:任务已排队但未执行,任务执行过程中存在间隔

原因:阻塞调用耗尽协作式线程池

  1. 检查所有线程上的任务执行间隔
  2. 检查是否存在阻塞原语
  3. 替换为异步等效方式

常见问题来源:

// ❌ Blocks cooperative thread
Task {
    semaphore.wait()  // NEVER do this
    // ...
    semaphore.signal()
}

// ❌ Synchronous file I/O in async context
Task {
    let data = Data(contentsOf: fileURL)  // Blocks
}

// ✅ Use async APIs
Task {
    let (data, _) = try await URLSession.shared.data(from: fileURL)
}

调试标志:

SWIFT_CONCURRENCY_COOPERATIVE_THREAD_BOUNDS=1

用于检测异步上下文中的不安全阻塞。

工作流 4:优先级反转

症状:高优先级任务等待低优先级任务

  1. 在 Instruments 中检查任务优先级
  2. 沿等待链追踪
  3. 确保关键路径使用适当的优先级
// ✅ Explicit priority for critical work
Task(priority: .userInitiated) {
    await criticalUIUpdate()
}

线程池模型

Swift 使用与 CPU 核心数相匹配的协作式线程池:

方面GCDSwift Concurrency
线程无限制增长固定为核心数
阻塞创建新线程挂起并释放线程
依赖关系隐藏由运行时跟踪
上下文切换完整的内核切换轻量级续体

阻塞为何后果严重:

  • 每个被阻塞的线程都会占用内存和内核结构
  • 线程数量有限,线程被阻塞就无法取得进展
  • 线程池耗尽会导致应用死锁

快速检查(性能分析前)

先运行以下检查:

  1. 工作是否真的异步?

    • 查找挂起点(await)
    • 异步函数中的同步代码仍会造成阻塞
  2. 是否在 await 期间持有锁?

    // ❌ Deadlock risk
    mutex.withLock {
        await something()  // Never!
    }
    
  3. 任务是否处于紧密循环中?

    // ❌ Overhead may exceed benefit
    for item in items {
        Task { process(item) }
    }
    
    // ✅ Structured concurrency
    await withTaskGroup(of: Void.self) { group in
        for item in items {
            group.addTask { process(item) }
        }
    }
    
  4. 是否在异步上下文中使用 DispatchSemaphore?

    • 始终不安全——改用 withCheckedContinuation

常见问题摘要

问题Instruments 中的症状修复方法
MainActor 过载主线程上出现较长的蓝色条Task.detached、nonisolated
Actor 争用红蓝比例较高拆分 actor、使用 nonisolated
线程耗尽所有线程上都存在间隔移除阻塞调用
优先级反转高优先级任务等待低优先级任务检查任务优先级
任务过多任务创建开销使用任务组

安全与不安全的原语

与协作式线程池兼容:

  • await、actors、任务组
  • os_unfair_lock、NSLock(临界区较短)
  • Mutex(iOS 18+)

不安全(会破坏前向进展):

  • DispatchSemaphore.wait()
  • pthread_cond_wait
  • 同步文件/网络 I/O
  • 在 Task 中调用 Thread.sleep()

资源

WWDC:2022-110350、2021-10254

文档:/xcode/improving-app-responsiveness

技能:axiom-swift-concurrency、axiom-performance-profiling、axiom-synchronization、axiom-lldb(交互式检查线程状态)

评论

支持 Markdown