iOS 4使用4×4矩阵加速Cblas
我一直在研究iOS 4中提供的Accelerate框架。具体来说,我尝试在C中的线性代数库中使用Cblas例程。现在我无法使用这些函数给我任何超过基本程序的性能提升。 具体来说,是4×4矩阵乘法的情况。 无论何时我无法利用矩阵的仿射或同质性质,我一直在使用这个例程(删节):
float *mat4SetMat4Mult(const float *m0, const float *m1, float *target) { target[0] = m0[0] * m1[0] + m0[4] * m1[1] + m0[8] * m1[2] + m0[12] * m1[3]; target[1] = ...etc... ... target[15] = m0[3] * m1[12] + m0[7] * m1[13] + m0[11] * m1[14] + m0[15] * m1[15]; return target; }
Cblas的等效函数调用是:
cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, 4, 4, 4, 1.f, m0, 4, m1, 4, 0.f, target, 4);
比较两者,通过使它们运行大量充满随机数的预先计算的矩阵(每个函数每次都获得完全相同的输入),当使用C clock()函数计时时,Cblas例程执行速度大约慢4倍。 。
这对我来说似乎不对,而且我感觉我在某处做错了什么。 我是否必须以某种方式启用设备的NEON设备和SIMDfunction? 或者我不希望用这么小的矩阵获得更好的性能?
非常感谢,
巴斯蒂安
BLAS和LAPACK库设计用于我认为的“中到大矩阵”(一边从几十到几万)。 它们将为较小的矩阵提供正确的结果,但性能不会尽可能好。
有几个原因:
- 为了提供最佳性能,必须内联3×3和4×4矩阵操作,而不是在库中; 进行函数调用的开销太大而无法克服,因为要完成的工作很少。
- 一组完全不同的接口是提供最佳性能所必需的。 矩阵乘法的BLAS接口采用变量来指定计算中涉及的矩阵的大小和前导维度,更不用说是否转置矩阵和存储布局。 所有这些参数使库变得强大,并且不会损害大型矩阵的性能。 但是,当它完成确定您正在进行4×4计算时,专用于执行4×4矩阵运算的function已经完成。
这对您意味着什么:如果您希望提供专用的小矩阵操作,请访问bugreport.apple.com并提交请求此function的错误。
Apple WWDC2010的演示文稿表示,即使是3×3矩阵操作,Accelerate仍然应该加速,所以我认为你应该看到4×4略有改进。 但是你需要考虑的是Accelerate&NEON旨在大大加速整数运算,但不一定是浮点运算。 你没有提到你的CPU处理器,似乎Accelerate将使用NEON或VFP进行浮点运算,具体取决于你的CPU。 如果它使用NEON指令进行32位浮点运算,那么它应该运行得很快,但如果它使用VFP进行32位浮点运算或64位双运算,那么运行速度非常慢(因为VFP实际上不是SIMD)。 因此,您应该确保使用Accelerate进行32位浮点运算,并确保它将使用NEON而不是VFP。
另一个问题是即使它确实使用了NEON,也不能保证你的C编译器会生成比没有NEON指令的简单C函数更快的NEON代码,因为GCC之类的C编译器经常生成可怕的SIMD代码,可能运行速度较慢比标准代码。 这就是为什么它总是很重要的是测试生成的代码的速度,并可能手动查看生成的汇编代码,看看你的编译器是否生成了错误的代码。
- UISwipeGestureRecognizer刷卡长度
- ViewControllers的NSMutableArray
- UITableView – 如何保持表格行固定为用户滚动
- 为NSFetchedResultsControllerdynamic设置fetchLimit
- iOS:以编程方式检测iOS应用程序安装的源代码(在安装的应用程序中)
- 不兼容的指针types使用UItableViewCelltypes的expression式初始化“CustomCellView *”
- OpenGL ES 2d渲染成图像
- 什么是__NSArrayI和__NSArrayM? 如何转换为NSArray?
- 如何安装cocoapods?