Броненосец против умножения векторов петли - PullRequest
0 голосов
/ 06 декабря 2018

Я хочу сравнить производительность Armadillo, когда мне нужно поэлементно умножить два комплексных вектора.Я написал простой тест, который рассчитывает время обработки.Умножение реализовано двумя способами: поэлементное умножение в Armadillo и простой цикл for над std :: vector.Вот источник теста:

#include <iostream>
#include <armadillo>
#include <stdlib.h>
using namespace std;
using namespace arma;
#include <complex>
#include <chrono>
using namespace std::chrono;
#define VEC_SIZE 204800
main(int argc, char** argv) {

    const int iterations = 1000;

    cout << "Armadillo version: " << arma_version::as_string() << endl;
    //duration<double> lib_cnt, vec_cnt;
    uint32_t lib_cnt = 0, vec_cnt = 0;

    for (int it = 0; it < iterations; it++) {
        // init input vectors
        std::vector<complex<float>> vf1(VEC_SIZE);
        std::fill(vf1.begin(), vf1.end(), complex<float>(4., 6.));
        std::vector<complex<float>> vf2(VEC_SIZE);
        std::fill(vf2.begin(), vf2.end(), 5.);

        std::vector<complex<float>> vf_res(VEC_SIZE);

        // init arma vectors
        Col<complex<float>> vec1(vf1);
        Col<complex<float>> vec2(vf2);


        // time for loop duration
        auto t0 = high_resolution_clock::now();
        for (int vec_idx = 0; vec_idx < VEC_SIZE; vec_idx++) {
            vf_res[vec_idx] = vf1[vec_idx] * vf2[vec_idx];
        }
        auto t1 = high_resolution_clock::now();

        vec_cnt += duration_cast<milliseconds>(t1 - t0).count();

        for (int vec_idx = 0; vec_idx < VEC_SIZE; vec_idx++) {
            complex<float> s = vf_res[vec_idx];
        }


        Col<complex<float>> mul_res(VEC_SIZE);

        // time arma element wise duration
        t0 = high_resolution_clock::now();
        mul_res = vec1 % vec2;
        t1 = high_resolution_clock::now();
        lib_cnt += duration_cast<milliseconds>(t1 - t0).count();

    }
    cout << "for loop time " << vec_cnt << " msec\n";
    cout << "arma time " << lib_cnt << " msec\n";

    return 0;
}

Результат, если следующее:

$ g++ example1.cpp -o example1 -O2 -larmadillo 
$ ./example1
Armadillo version: 9.200.5 (Carpe Noctem)
for loop time 2060 msec
arma time 3049 msec

Я ожидал, что броненосец умножится быстрее, чем простой цикл for.Или я не прав?Ожидается ли, что цикл for умножает два вектора быстрее?

1 Ответ

0 голосов
/ 06 декабря 2018

Это не ответ на проблему, скорее наблюдение.Если вы реструктурируете свой код в два отдельных цикла как:

#define VEC_SIZE 204800
main(int argc, char** argv)
{
    const int iterations = 1000;
    cout << "Armadillo version: " << arma_version::as_string() << endl;
    //duration<double> lib_cnt, vec_cnt;
    uint32_t lib_cnt = 0, vec_cnt = 0;

    // init input vectors
   std::vector<complex<float>> vf1(VEC_SIZE);
   std::fill(vf1.begin(), vf1.end(), complex<float>(4., 6.));
   std::vector<complex<float>> vf2(VEC_SIZE);
   std::fill(vf2.begin(), vf2.end(), 5.);
   std::vector<complex<float>> vf_res(VEC_SIZE);

   // init arma vectors
   Col<complex<float>> vec1(vf1);
   Col<complex<float>> vec2(vf2);
   Col<complex<float>> mul_res(VEC_SIZE);
   high_resolution_clock::time_point t0,t1;
   for (int it = 0; it < iterations; it++){
      // time for loop duration
      t0 = high_resolution_clock::now();
      for (int vec_idx = 0; vec_idx < VEC_SIZE; vec_idx++){
          vf_res[vec_idx] = vf1[vec_idx] * vf2[vec_idx];
      }
      t1 = high_resolution_clock::now();
      vec_cnt += duration_cast<milliseconds>(t1 - t0).count();
#if 1
      }
      for (int it = 0; it < iterations; it++){
#endif
      // time arma element wise duration
      t0 = high_resolution_clock::now();
      mul_res = vec1 % vec2;
      t1 = high_resolution_clock::now();
      lib_cnt += duration_cast<milliseconds>(t1 - t0).count();
    }
    cout << "for loop time " << vec_cnt << " msec\n";
    cout << "arma time " << lib_cnt << " msec\n";

    return 0;
}

, то результат переходит от

Armadillo version: 8.500.1 (Caffeine Raider)
for loop time 169 msec
arma time 244 msec

к

Armadillo version: 8.500.1 (Caffeine Raider)
for loop time 187 msec
arma time 22 msec

, что больше похоже на ожидаемыйрезультат.Однако я не могу объяснить, почему ...

Скомпилировано с gcc7.3.0 и openBlas на Core i5 M520, Ubuntu 18.04

...