diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt index 58af79351..3f7211777 100644 --- a/unsupported/test/CMakeLists.txt +++ b/unsupported/test/CMakeLists.txt @@ -17,6 +17,7 @@ ei_add_test(BVH) ei_add_test(matrixExponential) ei_add_test(alignedvector3) ei_add_test(FFT) +ei_add_test(nesting_profiling) find_package(FFTW) if(FFTW_FOUND) diff --git a/unsupported/test/nesting_profiling.cpp b/unsupported/test/nesting_profiling.cpp new file mode 100644 index 000000000..c19081e5a --- /dev/null +++ b/unsupported/test/nesting_profiling.cpp @@ -0,0 +1,199 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Hauke Heibel +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#include "main.h" + +#define EIGEN_OLD_NESTED + +#include "Eigen/Core" +#include "Eigen/Array" +#include "Eigen/Geometry" + +#include "Bench/BenchTimer.h" + +using namespace Eigen; + +struct Transform2D +{ + static void run(int num_runs) + { + const Matrix2d T = Matrix2d::Random(); + const Vector2d t = Vector2d::Random(); + const Matrix2Xd pts = Matrix2Xd::Random(2,100); + + Matrix2Xd res; + for (int i=0; i(t); + } +}; + +struct ColwiseTransform2D +{ + static void run(int num_runs) + { + const Matrix2d T = Matrix2d::Random(); + const Vector2d t = Vector2d::Random(); + const Matrix2Xd pts = Matrix2Xd::Random(2,100); + + Matrix2Xd res; + for (int i=0; i(t); + } +}; + +struct LinearCombination +{ + typedef Eigen::Matrix Matrix2x4d; + + static void run(int num_runs) + { + const Matrix2Xd pts = Matrix2Xd::Random(2,100); + const Matrix2x4d coefs = Matrix2x4d::Random(); + + Matrix2x4d linear_combined = Matrix2x4d::Zero(); + for (int i=0; i(coefs.row(r)); + } +}; + +template +struct VectorAddition +{ + typedef VectorType ReturnType; + EIGEN_DONT_INLINE static VectorType run(int) + { + VectorType a,b,c,d; + return a+b+c+d; + } +}; + +template +struct MatrixProduct +{ + typedef MatrixType ReturnType; + EIGEN_DONT_INLINE static MatrixType run(int num_runs) + { + MatrixType a,b; + return a*b; + } +}; + +template +struct MatrixScaling +{ + typedef MatrixType ReturnType; + EIGEN_DONT_INLINE static MatrixType run(int num_runs) + { + ei_traits::Scalar s; + MatrixType a,b; + return s*a; + } +}; + +template +EIGEN_DONT_INLINE void run(int num_runs) +{ + for (int outer_runs=0; outer_runs<30; ++outer_runs) + { + //BenchTimer timer; + //const double start = timer.getTime(); + { + TestFunction::run(num_runs); + } + //const double stop = timer.getTime(); + //std::cout << (stop-start)*1000.0 << " ms" << std::endl; + } +} + +template +EIGEN_DONT_INLINE void run_direct(int num_runs = 1) +{ + for (int outer_runs=0; outer_runs<30; ++outer_runs) + { + // required to prevent that the compiler replaces the run-call by nop + typename TestFunction::ReturnType return_type; + for (int i=0; i(num_runs); + run(num_runs); + run(num_runs); + } + const double stop = timer.getTime(); + std::cout << (stop-start)*1000.0 << " ms" << std::endl; + + // leads to identical assembly + run_direct< MatrixProduct >(); + run_direct< MatrixProduct >(); + run_direct< MatrixProduct >(); + + // leads to identical assembly + run_direct< MatrixScaling >(); + run_direct< MatrixScaling >(); + run_direct< MatrixScaling >(); + + // leads to better assembly + run_direct< VectorAddition >(); + run_direct< VectorAddition >(); + run_direct< VectorAddition >(); +}