我正在Zynq MPSOC Cortex-A53(Armv7 / Armv8)上开发嵌入式软件以进行图像处理,并且在开发特定算法时需要一些帮助。
该算法涉及复杂矩阵的反演,最大尺寸可达30x30。 (通过复数矩阵,我的意思是具有实部和虚部的复数浮点数。)
最重要的约束显然是时序约束:我们使用ARM NEON SIMD开发算法的速度更快。
为此,我目前正在测试 Eigen v3.3.5 库。 我写了代码进行求逆,对于矩阵24x24(类型为double double,函数 Eigen :: MatrixXcd :: inverse()):我得到的平均持续时间为 10,5毫秒。
我的代码:
#include <complex>
#include <cmath>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <Eigen/Dense>
static const unsigned int N_ROWS = 24;
static const unsigned int N_COLS = 24;
static const unsigned int NB_test = 20U;
// MAIN
int main(int argc, char** argv)
{
TimeTools TheTimer;
Eigen::MatrixXcd Matrix_cpx(N_ROWS, N_COLS);
Eigen::MatrixXcd Matrix_cpx_inv;
F32 ChronoResult[NB_test] = {0.0};
for(unsigned int TestIdx = 0U; TestIdx < NB_test; TestIdx ++)
{
// Get random matrix
Matrix_cpx = Eigen::MatrixXcd::Random(N_ROWS, N_COLS);
TheTimer.StartChrono();
// Inverse matrix
Matrix_cpx_inv = Matrix_cpx.inverse();
TheTimer.StopChrono();
// Save chrono
ChronoResult[TestIdx] = TheTimer.GetChronoValue();
}
std::cout << "\nM matrix is:\n" << Matrix_cpx << std::endl;
std::cout << "\nM_inv matrix is:\n" << Matrix_cpx_inv << std::endl;
F64 SumChrono = 0.0;
for(unsigned int TestIdx = 0U; TestIdx < NB_test; TestIdx ++)
{
std::cout << "\nMatrix_Inversion duration[" << TestIdx << "] = "<< ChronoResult[TestIdx] << " ms" << std::endl;
SumChrono += ChronoResult[TestIdx];
}
std::cout << "\nMatrix_Inversion average duration = "<< (SumChrono / NB_test) << " ms" << std::endl;
return 0;
}
注意:在TimeTools后面,使用了 gettimeofday()。
我的目标是加快矩阵求逆速度。 因此,我需要您的帮助:如何使其运行更快?
我知道Eigen可以使用ARM NEON SIMD来优化某些功能,但是我不确定Eigen确实将其用于矩阵求逆。怎么知道的?
我需要设置一个选项(= define)来启用NEON吗?还是其他可以优化特征码的选项?
注意:
提前谢谢您。
此致
洛朗。
更新
我忘记了优化标志...使用-O3
编译器选项,我得到了 0.82 ms 持续时间。
欢迎提出更多优化建议!
UPDATE2
使用ffast-math
构建选项,我获得了 0.4 ms 持续时间。
我一直在寻找更快的实现方式!