用 Accelerate 提升性能并集成加密归档
Use Accelerate to improve performance and incorporate encrypted archives
2021年6月10日
一句话判断
Accelerate 框架在 iOS 15 中新增了加密归档(Encrypted Archive)支持——用 Apple 独有的加密算法压缩和保护数据,性能比 CommonCrypto 好得多。
这场 Session 讲了什么
Session 分为两部分:前半部分介绍了 Accelerate 框架的性能优化能力,后半部分重点讲解了新增的加密归档 API。
Accelerate 是 Apple 的底层计算框架,提供向量运算、矩阵运算、信号处理和图像处理的硬件加速实现。Session 展示了几个常见的使用场景:用 vDSP 做音频处理、用 vImage 做图像处理、用 BNNS 做简单的神经网络推理。这些操作用 Accelerate 比用纯 Swift 实现快 10-100 倍。
加密归档是 iOS 15 中新增的功能。它提供了端到端加密的压缩归档格式,基于 Apple 的专有算法(结合了 AES 和自定义压缩)。主要用例是安全地在设备和服务器之间传输敏感数据,或在本地安全存储加密备份。
值得深挖的点
加密归档 vs CommonCrypto
CommonCrypto 提供 AES 等标准加密算法,但它只管加密不管压缩和归档。如果你要”加密压缩一堆文件”,需要自己组合压缩(zlib)和加密(AES),还要处理文件元数据的保护。加密归档 API 把这些一步到位——创建归档时同时压缩和加密,读取时同时解密和解压。而且 Apple 的实现利用了硬件加速的 AES 指令,性能比 CommonCrypto 的软件实现快。
vDSP 在音频处理中的实际收益
Session 用一个音频频谱分析的例子展示了 vDSP 的威力。对一段音频做 FFT(快速傅里叶变换),纯 Swift 实现需要几百毫秒,vDSP 只需要不到 1 毫秒。差距来自 vDSP 直接调用 Neon SIMD 指令,一个 CPU 周期处理 4 个浮点数。
代码片段
创建和读取加密归档
import Accelerate
// 创建加密归档
func createEncryptedArchive(data: Data, password: String) throws -> Data {
let archive = try EncryptedArchive.create(
data: data,
password: password,
compression: .lz4 // 使用 LZ4 压缩算法
)
return archive
}
// 读取加密归档
func readEncryptedArchive(archiveData: Data, password: String) throws -> Data {
let data = try EncryptedArchive.open(
data: archiveData,
password: password
)
return data
}
使用 vDSP 做音频 FFT
import Accelerate
// 计算音频数据的频谱
func computeSpectrum(audioSamples: [Float]) -> [Float] {
let length = audioSamples.count
let log2n = vDSP_Length(log2(Float(length)))
// 创建 FFT setup
let fftSetup = vDSP_create_fftsetup(log2n, FFTRadix(kFFTRadix2))!
// 将音频数据拆分为实部和虚部
var realPart = [Float](repeating: 0, count: length / 2)
var imagPart = [Float](repeating: 0, count: length / 2)
audioSamples.withUnsafeBufferPointer { samples in
var splitComplex = DSPSplitComplex(realp: &realPart, imagp: &imagPart)
// 执行 FFT
vDSP_fft_zrip(fftSetup, &splitComplex, 1, log2n, FFTDirection(FFT_FORWARD))
}
// 计算幅度
var magnitudes = [Float](repeating: 0, count: length / 2)
var splitComplex = DSPSplitComplex(realp: &realPart, imagp: &imagPart)
vDSP_zvabs(&splitComplex, 1, &magnitudes, 1, vDSP_Length(length / 2))
vDSP_destroy_fftsetup(fftSetup)
return magnitudes
}
使用 vImage 做图像处理
import Accelerate
// 高效调整图片大小(比 UIKit 的缩放快 5-10 倍)
func resizeImage(source: CGImage, targetSize: CGSize) -> CGImage? {
let sourceWidth = vImagePixelCount(source.width)
let sourceHeight = vImagePixelCount(source.height)
let destWidth = vImagePixelCount(Int(targetSize.width))
let destHeight = vImagePixelCount(Int(targetSize.height))
var sourceBuffer = vImage_CGImageFormat(
bitsPerComponent: 8, bitsPerPixel: 32,
colorSpace: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.first.rawValue)
)!.createBuffer(from: source)!
var destBuffer = vImage_Buffer()
vImageBuffer_Init(&destBuffer, destHeight, destWidth, 32, vImage_Flags(kvImageNoFlags))
// Lanczos 重采样,质量高于双线性插值
vImageScale_ARGB8888(&sourceBuffer, &destBuffer, nil, vImage_Flags(kvImageHighQualityResampling))
return destBuffer.createCGImage(format: sourceBuffer.format)
}
最佳实践
性能敏感场景: 任何涉及大量浮点运算的场景(音频处理、图像处理、科学计算)都应该用 Accelerate 而不是纯 Swift。vDSP 用于 1D 信号,vImage 用于 2D 图像,vForce 用于数学函数。这些 API 直接调用 CPU 的 SIMD 指令,无法被编译器自动优化替代。
加密存储: 需要加密归档数据的场景(离线缓存敏感数据、导出加密备份),使用新的加密归档 API 比 CommonCrypto + zlib 的组合更简单更安全。但注意加密归档格式是 Apple 专有的,无法在非 Apple 平台上读取。
还有什么值得关注
- Accelerate 的 BNNS(Basic Neural Network Subroutines)支持了更多层的类型,可以用来做轻量的推理任务。
- vImage 新增了对多平面图像格式的支持(如 YUV 420),方便视频处理。
- 加密归档支持增量写入,适合大文件的加密传输。