Замедляет ли библиотека броненосцев выполнение матричных операций? - PullRequest
0 голосов
/ 17 мая 2018

Я преобразовал код MATLAB в C ++, чтобы ускорить его, используя библиотеку Armadillo для обработки матричных операций в C ++, но на удивление он в 10 раз медленнее, чем код MATLAB!

Итак, я тестируюБиблиотека броненосца, чтобы увидеть, если это причина.Приведенный ниже код представляет собой простой тестовый код, который инициализирует две матрицы, складывает их вместе и сохраняет результат в новой матрице.Одна часть кода использует библиотеку Armadillo, а другая - нет.Секция с использованием Armadillo слишком медленная (обратите внимание на прошедшее время).

Действительно ли это замедляет выполнение (хотя оно должно ускорить его) или я что-то упускаю?

#include<iostream>
#include<math.h>
#include<chrono>
#include<armadillo>
using namespace std;
using namespace arma;
int main()
 {
   auto start = std::chrono::high_resolution_clock::now();
   double a[100][100];
   double b[100][100];
   double c[100][100];
   for (int i = 0; i < 100; i++)
     {
       for (int j = 0; j < 100; j++)
         {
           a[i][j] = 1;
           b[i][j] = 1;
           c[i][j] = a[i][j] + b[i][j];
         }
     }

     auto finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = finish - start;
    std::cout << "Elapsed time: " << elapsed.count() << " s\n";
    auto start1 = std::chrono::high_resolution_clock::now();
    mat a1=ones(100,100);
   mat b1=ones(100,100);
   mat c1(100,100);
   c1 = a1 + b1;
   auto finish1 = std::chrono::high_resolution_clock::now();
   std::chrono::duration<double> elapsed1 = finish1 - start1;
   std::cout << "Elapsed time: " << elapsed1.count() << " s\n";
   return 0;


}

Вот ответ, который я получаю:

Elapsed time: 5.1729e-05 s
Elapsed time: 0.00025536 s

Как видите, броненосец значительно медленнее!Лучше не использовать библиотеку Armadillo?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Прежде всего, убедитесь, что библиотеки blas и lapack включены, есть инструкции на Armadillo doc .Во-вторых, это может быть более обширное распределение памяти в броненосце.Если вы реструктурируете свой код, чтобы сначала выполнить инициализацию памяти как

#include<iostream>
#include<math.h>
#include<chrono>
#include<armadillo>
using namespace std;
using namespace arma;
int main()
 {
   double a[100][100];
   double b[100][100];
   double c[100][100];
   mat a1=ones(100,100);
   mat b1=ones(100,100);
   mat c1(100,100);

   auto start = std::chrono::high_resolution_clock::now();
   for (int i = 0; i < 100; i++)
     {
       for (int j = 0; j < 100; j++)
         {
           a[i][j] = 1;
           b[i][j] = 1;
           c[i][j] = a[i][j] + b[i][j];
         }
     }
   auto finish = std::chrono::high_resolution_clock::now();
   std::chrono::duration<double> elapsed = finish - start;
   std::cout << "Elapsed time: " << elapsed.count() << " s\n";

   auto start1 = std::chrono::high_resolution_clock::now();
   c1 = a1 + b1;
   auto finish1 = std::chrono::high_resolution_clock::now();
   std::chrono::duration<double> elapsed1 = finish1 - start1;
   std::cout << "Elapsed time: " << elapsed1.count() << " s\n";

   return 0;
}

С этим я получил результат:

Elapsed time: 0.000647521 s
Elapsed time: 0.000353198 s

Я скомпилировал его (в Ubuntu 17.10): g++ prog.cpp -larmadillo

0 голосов
/ 17 мая 2018

Я полагаю, что проблема в том, что вы вообще не используете броненосец.Вы уникально использовали его для создания переменных, которые немного сложнее, чем обычные двумерные массивы C ++, но на самом деле ничего более.Armadillo может сделать для вас очень быстрые матричные операции, как в c1=a1+b1;, без циклов.

Но если вы просто запишите это как поэлементную операцию, вы просто не будете использовать броненосец.Это то же самое, что использовать MATLAB для умножения матриц, но писать умножение матриц самостоятельно.Вы не используете библиотеки MATLAB!

...