Я пытаюсь внутренне распараллелить функцию ODE, которая интегрирована с ODEINT.
Я сделал следующий небольшой пример
#include <iostream>
#include <chrono>
#include <Eigen/Dense>
#include <omp.h>
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/openmp/openmp.hpp>
#include <boost/numeric/odeint/external/eigen/eigen.hpp>
using namespace boost::numeric::odeint;
class System {
private:
Eigen::VectorXd _input_data;
public:
System( Eigen::VectorXd &input_data ) { _input_data = input_data; };
void operator() ( const Eigen::VectorXd &x , Eigen::VectorXd &dxdt , const double t ) {
double _sum = 0.;
#pragma omp parallel for reduction(+:_sum)
for(int k = 0; k < _input_data.size(); ++k) {
_sum += _input_data(k);
};
dxdt(0) = _sum;
};
};
int main() {
omp_set_num_threads(1);
Eigen::VectorXd input_data = Eigen::VectorXd::Zero(100);
System ode(input_data);
runge_kutta_dopri5<Eigen::VectorXd> rk5_stepper;
Eigen::VectorXd x = Eigen::VectorXd::Zero(1);
auto start = std::chrono::high_resolution_clock::now();
size_t steps = integrate_const(rk5_stepper, ode, x, 0., 1., 0.01);
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
std::cout << "Execution time: " << duration.count() / 1000000. << " sec" << std::endl;
return 0;
}
с файлом CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_COMPILER /usr/local/bin/gcc-9)
set(CMAKE_CXX_COMPILER /usr/local/bin/g++-9)
project(ODEINT_OPENMP_TEST)
set(CMAKE_CXX_STANDARD 14)
include_directories("/usr/local/include")
find_package(OpenMP REQUIRED)
add_executable(ODEINT_OPENMP_TEST main.cpp)
target_link_libraries(ODEINT_OPENMP_TEST PRIVATE OpenMP::OpenMP_CXX)
когда я пытаюсь использовать больше потоков через omp_set_num_threads(N)
, программа постоянно замедляется по сравнению с использованием только одного потока omp_set_num_threads(1)
. Программа становится примерно в 3 раза медленнее (на моей машине) при выборе N=2.
Интуитивно, правая функция должна работать быстрее параллельно? Я делаю что-то неправильно?