Xcode Instruments“兴趣点”下降间隔

问题描述 投票:0回答:1

tl;博士

在“兴趣点”工具中记录大量间隔时,我发现间隔从主窗格的图表中随机省略。其他人也看到这个问题吗?我是不是做错了什么?


我广泛使用 Xcode Instruments 来监控具有“兴趣点”间隔的异步工作。请参阅如何识别 Xcode Instruments 中的按键事件?

(郑重声明,还有其他工具,例如 WWDC 2022 的可视化和优化 Swift 并发中概述的工具,但对我来说,间隔仍然是我的“首选”工具。)

不管怎样,我可以创建一个兴趣点

OSLog
:

import os.log

let poi = OSLog(subsystem: "Test", category: .pointsOfInterest)

然后我可以做这样的事情:

let id = OSSignpostID(log: poi)
os_signpost(.begin, log: poi, name: #function, signpostID: id, …)

…

os_signpost(.end, log: poi, name: #function, signpostID: id)

然后我可以在 Instruments 中分析应用程序(来自 Xcode 的“产品”»“配置文件”或命令-i),从“时间分析”模板开始,我会得到应用程序执行的良好时间表。 (您还可以执行诸如右键单击间隔并设置检查范围之类的操作,从而将您对 CPU 或 RAM 或其他内容的调查范围缩小到某个明确定义的代码执行间隔。)

因此,例如,我运行

foo
,然后运行
bar
,最后运行
baz
,每次记录它们的间隔,我得到:

一切都好。 (我有点希望这张图是按时间顺序排列的,而不是按字母顺序排列的,但这不是我的问题。)

但最近,我越来越多地看到图表中间隔的丢失。例如,在这里我运行了 50 次迭代,每次都有四个并发任务,中间有一个暂停,我得到以下结果:

但请注意,在第 2、16、20、40 和 46 次迭代时,图中缺少间隔。虽然会被丢弃,但我看到它的概率在 5-15% 之间。在下部的“详细信息”面板中,我可以看到所有间隔实际上都被仪器成功捕获,但有些间隔根本没有在主窗格的可视化图表中表示。 (并且,只有通过进行较大的间隔,我才最终注意到缺失的间隔与 Instruments 停止使用该通道并创建新通道这一事实之间的相关性。)

我测试过的一些东西包括:

  • 更换设备似乎没有什么区别。我在 iOS 设备、模拟器或 macOS 应用程序上看到了这一点。他们都表现出相似的行为。
  • 我最初在测试计算密集型并行计算时遇到过这种情况,但意识到我在对 CPU 影响可以忽略不计的情况下也遇到了同样的问题(例如,上面的情况是
    Task.sleep
    )。
  • 我知道这不是一个“必须在同一个线程上完成”的问题,因为我在使用同步代码的间隔时也看到了这个问题(我显然在同一个线程上)。
  • 我在 Instruments 中使用延迟和立即记录模式进行了测试。 (我通常使用前者,因为后者可能会导致重负载下事件丢失。)
  • 我第一次在 Xcode 15.0 中注意到这一点,但 15.0.1 也有同样的问题。
  • 控制台中没有错误或消息。

其他人也经历过这种行为吗?这是怎么回事?


对于那些感兴趣的人,这是在 Instruments 中生成上述屏幕快照的代码:

let poi = OSLog(subsystem: "Test", category: .pointsOfInterest)

struct ContentView: View {
    @State var status = "Not started…"
    @State var buttonsDisabled = false
    
    var body: some View {
        VStack {
            Text("Instruments’ “Points of Interest” experiment")
            Text(status)
            Button("Test Async-Await Times") {
                Task {
                    status = "Starting"
                    buttonsDisabled = true
                    for i in 0 ..< 50 {
                        try await fourConcurrentTasks()
                        status = "Finished \(i) … still running"
                        try await Task.sleep(for: .milliseconds(500))
                    }
                    status = "All done"
                    buttonsDisabled = false
                }
            }
            .disabled(buttonsDisabled)
        }
        .padding()
    }

    func fourConcurrentTasks() async throws {
        try await withThrowingTaskGroup(of: Void.self) { group in
            for index in 0..<4 {
                group.addTask {
                    let id = OSSignpostID(log: poi)
                    os_signpost(.begin, log: poi, name: #function, signpostID: id, "%d: %d", run, index)

                    try await Task.sleep(for: .seconds(1))

                    os_signpost(.end, log: poi, name: #function, signpostID: id)
                }
            }
            
            try await group.waitForAll()
        }
    }
}
xcode instruments xcode-instruments
1个回答
0
投票

我怀疑这只是“兴趣点”工具中的一个错误,因为:

  • 详细信息窗格正确报告所有间隔。
  • 我还使用我自己的原始“自定义兴趣点”工具(下面的绿色)对其进行了测试,并且 Instruments 正确地呈现了它。该问题似乎与标准“兴趣点”工具(蓝色)无关:

我得出的结论是,这不是仪器中的问题,本身,而是特别是“兴趣点”工具中的问题。我已将其报告为错误 (FB13207499)。

© www.soinside.com 2019 - 2024. All rights reserved.