如何显着降低 iOS 应用中的能源影响?

How to significantly reduce Energy Impact in iOS app?

我正在开发具有 Vision 框架功能(处理 CoreML 模型)的 ARKit 应用程序。

loopCoreMLUpdate() 函数形成一个循环,导致 非常高的能量影响 (CPU=70%,GPU=66%)。

如何处理这个任务并将能量影响降低到低水平

有什么解决此循环问题的方法可以帮助我减少 CPU/GPU 工作量

这是我的代码:

import UIKit
import SpriteKit
import ARKit
import Vision

class ViewController: UIViewController, ARSKViewDelegate {

    @IBOutlet weak var sceneView: ARSKView!
    let dispatchQueueML = DispatchQueue(label: "AI")
    var visionRequests = [VNRequest]()

    // .........................................
    // .........................................

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let configuration = AROrientationTrackingConfiguration()
        sceneView.session.run(configuration)

        loopCoreMLUpdate()
    }

    func loopCoreMLUpdate() {          
        dispatchQueueML.async {
            self.loopCoreMLUpdate()  // SELF-LOOP LEADS TO A VERY HIGH IMPACT
            self.updateCoreML()
        }
    }

    func updateCoreML() {
        let piBuffer: CVPixelBuffer? = (sceneView.session.currentFrame?.capturedImage)
        if piBuffer == nil { return }
        let ciImage = CIImage(cvPixelBuffer: piBuffer!)
        let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage, options: [:])

        do {
            try imageRequestHandler.perform(self.visionRequests)
        } catch {
            print(error)
        }
    }
    // .........................................
    // .........................................
}

是的,您标记的行肯定是个大问题。你不是在这里循环;您正在尽可能快地生成新的异步任务,甚至在前一个任务完成之前。在任何情况下,您都试图在创建 CVPixelBuffers 之后更快地捕获它们,这是一种巨大的浪费。

如果你想捕捉帧,你不需要创建一个紧密的循环来对它们进行采样。您将自己设置为 ARSessionDelegate 并实现 session(_:didUpdate:)。当有可用的新框架时,系统会告诉您。 (可以创建您自己的渲染循环,但您不会在这里这样做,除非您真的需要自己的渲染管道,否则您不应该这样做。)

请记住,您很快就会收到很多帧。 30fps 或 60fps 很常见,但也可以高达 120fps。您不能使用所有的时间片(其他事情也需要处理器时间)。关键是您通常无法跟上帧速率,并且需要缓冲以供以后处理,或丢帧,或两者兼而有之。这是实时处理中非常正常的部分。

对于这种分类系统,您可能需要选择实际的帧率,可能低至 10-20fps,并跳帧以保持该速率。对几十个几乎相同的帧进行分类可能没有帮助。

也就是说,请确保您已阅读 Recognizing Objects in Live Capture。感觉这就是您要尝试做的事情,并且有很好的示例代码可用。