首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Accelerate框架执行标准化

使用Accelerate框架执行标准化
EN

Stack Overflow用户
提问于 2020-08-03 01:29:26
回答 2查看 114关注 0票数 0

我需要对包含RGB像素数据的Data执行简单的数学运算。目前我是这样做的:

代码语言:javascript
复制
let imageMean: Float = 127.5
let imageStd: Float = 127.5
let rgbData: Data // Some data containing RGB pixels 
let floats = (0..<rgbData.count).map {
    (Float(rgbData[$0]) - imageMean) / imageStd
}
return Data(bytes: floats, count: floats.count * MemoryLayout<Float>.size)

这是可行的,但是太慢了。我希望我可以使用Accelerate框架来更快地计算,但我不知道如何做到这一点。我保留了一些空间,这样它就不会在这个函数每次启动时都被分配,如下所示:

代码语言:javascript
复制
inputBufferDataNormalized = malloc(width * height * 3) // 3 channels RGB

我尝试了几个函数,比如vDSP_vasm,但是我不能让它工作。有人能告诉我如何使用它吗?基本上我需要替换这个map函数,因为它花费的时间太长了。而且,一直使用预先分配的空间可能会很棒。

EN

回答 2

Stack Overflow用户

发布于 2020-08-03 02:21:50

跟进我对你的其他相关问题的评论。您可以使用SIMD并行化操作,但需要将原始数组拆分为块。

这是一个简化的示例,它假设数组完全可以被64整除,例如,一个包含1024个元素的数组:

代码语言:javascript
复制
let arr: [Float] = (0 ..< 1024).map { _ in Float.random(in: 0...1) }
代码语言:javascript
复制
let imageMean: Float = 127.5
let imageStd: Float = 127.5

var chunks = [SIMD64<Float>]()
chunks.reserveCapacity(arr.count / 64)

for i in stride(from: 0, to: arr.count, by: 64) {
   let v = SIMD64.init(arr[i ..< i+64])

   chunks.append((v - imageMean) / imageStd) // same calculation using SIMD

}

现在,您可以使用下标访问每个chunk

代码语言:javascript
复制
var results: [Float] = []
results.reserveCapacity(arr.count)

for chunk in chunks {
   for i in chunk.indices {
      results.append(chunk[i])
   }
}

当然,如果数组不能被64整除,则需要处理余数。

票数 0
EN

Stack Overflow用户

发布于 2020-08-03 03:52:46

我已经找到了一种使用Accelerate来完成此任务的方法。首先,我为转换后的缓冲区预留空间,如下所示

代码语言:javascript
复制
var inputBufferDataRawFloat = [Float](repeating: 0, count: width * height * 3)

然后我可以像这样使用它:

代码语言:javascript
复制
let rawBytes = [UInt8](rgbData)
vDSP_vfltu8(rawBytes, 1, &inputBufferDataRawFloat, 1, vDSP_Length(rawBytes.count))
            
vDSP.add(inputBufferDataRawScalars.mean, inputBufferDataRawFloat, result: &inputBufferDataRawFloat)
vDSP.multiply(inputBufferDataRawScalars.std, inputBufferDataRawFloat, result: &inputBufferDataRawFloat)

return Data(bytes: inputBufferDataRawFloat, count: inputBufferDataRawFloat.count * MemoryLayout<Float>.size)

运行速度非常快。也许Accelerate有更好的功能,如果有人知道,请让我知道。它需要执行函数(A[n] + B) * C (或者确切地说是(A[n] - B) / C,但第一个函数可以转换为这个函数)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63219100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档