Как мне реализовать рекомендацию Эйгена по отключению распараллеливания / многопоточности - где и сколько токенов препроцессора? - PullRequest
0 голосов
/ 19 июня 2020

У меня есть небольшая программа, которая использует матрицы Eigen в нескольких файлах классов cpp, скажем, для MWE в main.cpp и MyClass.h.

#include <Eigen/Dense>
#include <parallel/algorithm>

using namespace std;


int main(int argc, char** argv) {

Eigen::MatrixXd hello = Eigen::MatrixXd::Random(1000,2); // make a large matrix so that 
//Eigen would want to use parallelisation

vector<Eigen::MatrixXd> my_container(1000,Eigen::MatrixXd::Random(1000,1000)); //make a large
//container so __gnu_parallel would want to use parallelisation

//a parallel loop here

__gnu_parallel::for_each(my_container.begin(),my_container.end(),[&hello]
(const Eigen::Ref<const Eigen::MatrixXd>& MyMat){
    MyMat * hello; //dense matrix multiplication which Eigen would parallelise
    });

    return 0;
}

Что рекомендует Эйген :

Согласно собственному описанию Эйгена здесь , я считаю, что умножение плотной матрицы и параллельный характер for_each l oop будут мешать таким образом, что мне пришлось бы выбирать между Eigen, выполняющим многопоточность, и в этом случае я мог бы переключиться с пространства имен __gnu_parallel на пространство имен __gnu_sequential или отключить распараллеливание Eigen.

Учитывая, что мои матрицы, как правило, меньше (в основном), чем используемые в этом примере я бы предпочел, чтобы мои циклы через контейнеры STL были параллельны, поэтому я хотел бы придерживаться __gnu_parallel::for_each, __gnu_parallel::transform et c.

Что мне нужно сделать

Следовательно, я считаю, что мне нужно определить токен препроцессора:

#define EIGEN_DONT_PARALLELIZE

Мой вопрос

  1. Верно ли это рассуждение? Т.е. если бы я не определял этот токен, не мешало бы распараллеливание __gnu_parallel и Eigen друг другу? Моя рабочая гипотеза - да.
  2. Где мне разместить определение токена, до или после #include <Eigen/Dense>?
  3. Что касается заголовочного файла, определяющего классы и методы MyClass.h, где у меня MyClass::MyMethod при использовании матриц Eigen, имеющих отдельное включение для библиотеки Eigen, нужны ли мне отдельные токены (желательно с защитой) в строках следующего фрагмента кода?

Код

#ifndef EIGEN_DONT_PARALLELIZE
#define EIGEN_DONT_PARALLELIZE
#endif
#include <Eigen/Dense>
    class MyClass 
            { //code using Eigen's matrices here};

Фон

Что касается фона, я видел это в одном из заголовков Eigen:

#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
#define EIGEN_HAS_OPENMP
#endif.

Большое спасибо!

...