Повторные обращения к CwiseUnaryView — лучше копировать в матрицу?

Как следует из названия, у меня есть пользовательская функция UnaryView, которая вызывается несколько раз в разных операциях (в основном умножение с другими матрицами). Например:

MatrixXd out = mat1.cview() * mat2;
MatrixXd out2 = mat1.cview() * mat3.transpose();

Не будет ли быстрее сначала скопировать пользовательское представление в отдельную матрицу и использовать его вместо этого? Например:

MatrixXd mat1_dbl = mat1.cview();
MatrixXd out = mat1_dbl * mat2;
MatrixXd out2 = mat1_dbl * mat3.transpose();

По сути, повторное использование UnaryView медленнее, чем копирование в матрицу и использование этого вместо этого?

Вы сравнивали это? Вы его скомпилировали и проверили, делает ли это Eigen автоматически?

chtz 09.04.2019 13:26

Я даже не думал тестировать, если честно. Это ответ на мой вопрос, извините за потраченное время!

AndrewrJ 09.04.2019 14:59

Вы можете написать это как ответ вместо редактирования вопроса.

chtz 09.04.2019 17:13
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
34
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Должен был сделать свой собственный бенчмаркинг. Тест Google показывает, что сначала копировать заметно быстрее:

2019-04-09 20:55:55
Running ./CView
Run on (16 X 4053.06 MHz CPU s)
CPU Caches:
  L1 Data 32K (x8)
  L1 Instruction 64K (x8)
  L2 Unified 512K (x8)
  L3 Unified 8192K (x2)
--------------------------------------------------------
Benchmark                 Time           CPU Iterations
--------------------------------------------------------
UnaryView_Repeat  147390919 ns  147385796 ns          5
UnaryView_Copy    139456051 ns  139451409 ns          5

Протестировано с:

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/fwd/mat.hpp>
#include <stan/math/fwd/core.hpp>
#include <benchmark/benchmark.h>

static void UnaryView_Repeat(benchmark::State& state) {
  using Eigen::MatrixXd;
  using stan::math::matrix_fd;

  matrix_fd m_fd1(1000, 1000);
  m_fd1.val_() = MatrixXd::Random(1000, 1000);
  m_fd1.d_() = MatrixXd::Random(1000, 1000);
  MatrixXd m_d2 = MatrixXd::Random(1000, 1000);


  for (auto _ : state) {
    MatrixXd out(1000,1000);

    out = m_fd1.val_() * m_d2 
            + m_fd1.val_().transpose() * m_d2
            + m_fd1.val_().array().exp().matrix();
  }
}
BENCHMARK(UnaryView_Repeat);

static void UnaryView_Copy(benchmark::State& state) {
  using Eigen::MatrixXd;
  using stan::math::matrix_fd;

  matrix_fd m_fd1(1000, 1000);
  m_fd1.val_() = MatrixXd::Random(1000, 1000);
  m_fd1.d_() = MatrixXd::Random(1000, 1000);
  MatrixXd m_d2 = MatrixXd::Random(1000, 1000);


  for (auto _ : state) {
    MatrixXd out(1000,1000);
    MatrixXd m_fd1_val = m_fd1.val_();

    out = m_fd1_val * m_d2 + m_fd1_val.transpose() * m_d2
            + m_fd1_val.array().exp().matrix();
  }
}
BENCHMARK(UnaryView_Copy);

BENCHMARK_MAIN();

Другие вопросы по теме