【问题标题】:How to compute the square root of a vector elementwise using vDSP / Accelerate in swift for iOS如何使用 vDSP / Accelerate in swift for iOS 计算向量元素的平方根
【发布时间】:2020-02-04 18:35:22
【问题描述】:

我有一个类似于[Float](repeating: 1.0, count: 42000) 的向量,我想使用 Accelerate 框架计算每个元素的平方根,但不存在与Apple Accelerate Framework scale and normalize a vector 中所述相反的vDSP_vsqrt 函数。我该怎么做?

【问题讨论】:

    标签: ios swift accelerate-framework


    【解决方案1】:

    vForce Swift 覆盖使语法更简单:

    vForce.sqrt(vector: AccelerateBuffer)
    

    看看:https://github.com/apple/swift/blob/master/stdlib/public/Darwin/Accelerate/vForce_Operations.swift

    ...和...

    https://developer.apple.com/videos/play/wwdc2019/718/

    【讨论】:

      【解决方案2】:

      看来要调用的正确函数是来自vForcevvsqrtf

      以下是the documentation 的用法示例:

      var x: [Float] = [100, 10000, 64, 144]
      var y = [Float](repeating: 0, count: x.count)
      var n = Int32(x.count)
      
      vvsqrtf(&y, &x, &n)
      
      print(y) // [10.0, 100.0, 8.0, 12.0]
      

      请注意,您还可以“就地”计算平方根:

      var data = [Float](repeating: 25.0, count: input.count)
      let n = Int32(data.count)
      
      vvsqrtf(&data, data, &n)
      

      【讨论】:

        【解决方案3】:

        我建议制作辅助函数来包装 vvsqrtf,以公开更 Swift 友好的 API:

        import Accelerate
        
        extension Array where Element == Float {
            func squareRootedElements() -> [Float] {
                if self.isEmpty { return [] }
        
                var output = Array(repeating: 0, count: self.count)
                var count = Int32(self.count)
        
                vvsqrtf(&output, self, &count)
        
                return output
            }
        
            mutating func squareRootElements() {
                if self.isEmpty { return }
        
                var count = Int32(self.count)
        
                vvsqrtf(&self, self, &count)
            }
        }
        
        var squares = stride(from: 0 as Float, through: 10, by: +1).map { $0 * $0 }
        print(squares)
        print(squares.squareRootedElements())
        

        【讨论】:

        • 不需要缓冲区指针,只需vvsqrtf(&output, self, &count)
        • @JeremyCochoy 哦,如果vvsqrtf 的第一个和第二个参数使用相同的缓冲区,它会就地覆盖吗?
        • @JeremyCochoy 更新:)
        • @gasher729 这不是真的。这里产生的唯一开销是函数调用的恒定时间开销,如果您担心,它甚至可以内联。它所做的事情与您自己拨打 vvsqrtf 所做的事情相同,但复制/粘贴更少
        • 此外,您的前提有点误导。您使用加速来加速可并行化操作。它的附加值是它可以在 CPU 或 GPU 中使用 SIMD 指令来加速你的代码,它的加速因子与你的数据大小成正比。它的增值不是消除单个快速函数调用的开销(更不用说这种开销在数据大小上是 O(1) 的事实)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-25
        相关资源
        最近更新 更多