Я занимаюсь разработкой встроенного программного обеспечения на Zynq MPSOC Cortex-A53 (Armv7 / Armv8) для обработки изображений, и мне нужна помощь для разработки конкретного алгоритма.
Алгоритм включает в себя инверсию сложной матрицы с большимиразмер до 30х30.(Под сложной матрицей я подразумеваю комплексное число с плавающей точкой с действительными и мнимыми частями.)
Очевидно, что наиболее значимым ограничением является ограничение по времени : мы используем для разработки наших алгоритмов с ARM NEON SIMD дляБыстрее.
Для этого я сейчас тестирую библиотеку Eigen v3.3.5 .Я написал код для инверсии и для матрицы 24x24 (тип complex 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 используетэто для обращения матрицы.Как это узнать?
Нужно ли устанавливать опцию (= определить), чтобы включить NEON?Или другие варианты, которые могут оптимизировать собственный код?
Примечания:
- Компилятор arm-linux-gnueabi-g ++ (32бит)
- Опции компилятора: -mcpu = cortex-a53 -mfloat-abi = softfp -mfpu = neon-vfpv4
- Процессор работает на частоте 1,2 ГГц.
Заранее благодарю.
С уважением,
Лоран.
ОБНОВЛЕНИЕ
Я забыл флаг оптимизации ..С опцией -O3
компилятор я получил 0,82 мс длительность.
Любые идеи по оптимизации больше будут приветствоваться!
UPDATE2
С опцией ffast-math
сборки я получил 0,4 мс длительность.
Я продолжаю искать более быструю реализацию!