我正在使用Accelerate框架在Swift中进行矩阵乘法。我使用了vDSP_mmulD,在iPhone6,6 plus和iPad Air模拟器(所有64位架构设备)上运行良好,但在任何32位架构设备上都无法工作。
似乎32位架构不识别vDSP_mmulD,程序无法构建。错误消息显示为“未解析的标识符‘vDSP_mmulD’”。有其他人看到过这个错误吗?请告诉我您的想法。我正在使用Xcode 6.1。
谢谢。
vDSP_mmulD一样快,并且在某些系统上要快得多(在iOS 8和Yosemite中,vDSP_mmulD 实际上只是 cblas_dgemm 的包装器),并且它应该可以在这里正常工作。
我怀疑您的构建在32位模拟器上失败了。在i386上,vDSP_mmulD实际上是围绕mmulD的宏,而Swift不完全支持C语言宏。
注意:我怀疑您可能正在使用3x3或4x4矩阵,在这种情况下,没有一个Accelerate例程真正符合您的要求(它们针对更大的矩阵);您需要内联向量序列,如<simd / matrix.h>中定义的序列。不幸的是,Swift不支持SIMD向量,因此这不是一个选项。此时,您最好的选择可能是简单地编写逐元素计算,并报告错误以请求Swift支持<simd / simd.h>接口。
Float
,在64位架构上使用Double
。 vDSP_mmulD
末尾的D
代表Double
,因此您需要能够在代码中使用32位架构上的Float
版本:vDSP_mmul
。#if...#else...#endif
预处理块来切换使用哪些方法(有关信息请参见本页面底部)。绕过Swift的严格静态类型的一个技巧是在文件顶部放置类似于这样的预处理块:#if arch(x86_64) || arch(arm64)
typealias M_Float = Double
let M_vDSP_mmul = vDSP_mmulD
// add Double versions of other Accelerate functions you need
#else
typealias M_Float = Float
let M_vDSP_mmul = vDSP_mmul
// add Float versions of other Accelerate functions you need
#endif
Float
或Double
,或在您的代码中始终使用哪种方法,您可以只使用M_Float
和您的M_...
版本的Accelerate函数:var number: M_Float = 0 // Double on 64-bit, Float on 32-bit
M_vDSP_mmul(...) // correct version either way