From e3a820f468596a8ca3b58e809ef51a0d6cd7affe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 23 Oct 2019 11:57:10 +0200 Subject: [PATCH] Math: benchmark basic Matrix operations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So I'm sure the next additions don't make things worse -- in the debug build, in particular. Current state: Starting Magnum::Math::Test::MatrixBenchmark with 14 test cases... INFO Benchmarking a debug build. BENCH [01] 102.25 ± 4.58 ns multiply3()@499x10000 (wall time) BENCH [02] 183.84 ± 7.75 ns multiply4()@499x10000 (wall time) BENCH [03] 329.84 ± 20.50 ns invert3()@49x10000 (wall time) BENCH [04] 442.08 ± 13.47 ns invert3GaussJordan()@49x10000 (wall time) BENCH [05] 331.23 ± 13.85 ns invert3Rigid()@49x10000 (wall time) BENCH [06] 206.01 ± 11.13 ns invert3Orthogonal()@49x10000 (wall time) BENCH [07] 1.01 ± 0.03 µs invert4()@49x10000 (wall time) BENCH [08] 826.77 ± 19.33 ns invert4GaussJordan()@49x10000 (wall time) BENCH [09] 520.12 ± 21.97 ns invert4Rigid()@49x10000 (wall time) BENCH [10] 344.20 ± 13.32 ns invert4Orthogonal()@49x10000 (wall time) BENCH [11] 61.00 ± 2.89 ns transformVector3()@999x10000 (wall time) BENCH [12] 61.55 ± 3.35 ns transformPoint3()@999x10000 (wall time) BENCH [13] 80.65 ± 2.99 ns transformVector4()@999x10000 (wall time) BENCH [14] 80.86 ± 3.32 ns transformPoint4()@999x10000 (wall time) Finished Magnum::Math::Test::MatrixBenchmark with 0 errors out of 5400 checks. --- src/Magnum/Math/Test/CMakeLists.txt | 2 + src/Magnum/Math/Test/MatrixBenchmark.cpp | 220 +++++++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 src/Magnum/Math/Test/MatrixBenchmark.cpp diff --git a/src/Magnum/Math/Test/CMakeLists.txt b/src/Magnum/Math/Test/CMakeLists.txt index 459935561..bd35181af 100644 --- a/src/Magnum/Math/Test/CMakeLists.txt +++ b/src/Magnum/Math/Test/CMakeLists.txt @@ -67,6 +67,8 @@ corrade_add_test(MathInterpolationBenchmark InterpolationBenchmark.cpp LIBRARIES corrade_add_test(MathConfigurationValueTest ConfigurationValueTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathStrictWeakOrderingTest StrictWeakOrderingTest.cpp LIBRARIES MagnumMathTestLib) +corrade_add_test(MathMatrixBenchmark MatrixBenchmark.cpp LIBRARIES MagnumMathTestLib) + set_property(TARGET MathVectorTest MathMatrixTest diff --git a/src/Magnum/Math/Test/MatrixBenchmark.cpp b/src/Magnum/Math/Test/MatrixBenchmark.cpp new file mode 100644 index 000000000..d2036a094 --- /dev/null +++ b/src/Magnum/Math/Test/MatrixBenchmark.cpp @@ -0,0 +1,220 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/Math/Matrix3.h" +#include "Magnum/Math/Matrix4.h" +#include "Magnum/Math/Algorithms/GaussJordan.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct MatrixBenchmark: Corrade::TestSuite::Tester { + explicit MatrixBenchmark(); + + void multiply3(); + void multiply4(); + + void invert3(); + void invert3GaussJordan(); + void invert3Rigid(); + void invert3Orthogonal(); + void invert4(); + void invert4GaussJordan(); + void invert4Rigid(); + void invert4Orthogonal(); + + void transformVector3(); + void transformPoint3(); + void transformVector4(); + void transformPoint4(); +}; + +MatrixBenchmark::MatrixBenchmark() { + addBenchmarks({&MatrixBenchmark::multiply3, + &MatrixBenchmark::multiply4}, 500); + + addBenchmarks({&MatrixBenchmark::invert3, + &MatrixBenchmark::invert3GaussJordan, + &MatrixBenchmark::invert3Rigid, + &MatrixBenchmark::invert3Orthogonal, + &MatrixBenchmark::invert4, + &MatrixBenchmark::invert4GaussJordan, + &MatrixBenchmark::invert4Rigid, + &MatrixBenchmark::invert4Orthogonal}, 50); + + addBenchmarks({&MatrixBenchmark::transformVector3, + &MatrixBenchmark::transformPoint3, + &MatrixBenchmark::transformVector4, + &MatrixBenchmark::transformPoint4}, 1000); +} + +typedef Math::Vector2 Vector2; +typedef Math::Vector3 Vector3; +typedef Math::Vector4 Vector4; +typedef Math::Matrix4 Matrix4; +typedef Math::Matrix3 Matrix3; + +enum: std::size_t { Repeats = 10000 }; + +using namespace Literals; + +const Matrix3 Data3Orthogonal = Matrix3::rotation(134.7_degf); +const Matrix3 Data3Rigid = Data3Orthogonal*Matrix3::translation(Vector2::yAxis()); +const Matrix3 Data3 = Data3Orthogonal*Matrix3::scaling(Vector2{2.5f})*Matrix3::translation(Vector2::yAxis()); + +const Matrix4 Data4Orthogonal = Matrix4::rotation(134.7_degf, Vector3{1.0f, 3.0f, -1.4f}.normalized()); +const Matrix4 Data4Rigid = Data4Orthogonal*Matrix4::translation(Vector3::zAxis()); +const Matrix4 Data4 = Data4Orthogonal*Matrix4::scaling(Vector3{2.5f})*Matrix4::translation(Vector3::zAxis()); + +void MatrixBenchmark::multiply3() { + Matrix3 a = Data3; + CORRADE_BENCHMARK(Repeats) { + a = a*a; + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::multiply4() { + Matrix4 a = Data4; + CORRADE_BENCHMARK(Repeats) { + a = a*a; + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::invert3() { + Matrix3 a = Data3; + CORRADE_BENCHMARK(Repeats) { + a = a.inverted(); + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::invert3GaussJordan() { + Matrix3 a = Data3; + CORRADE_BENCHMARK(Repeats) { + a = Math::Algorithms::gaussJordanInverted(a); + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::invert3Rigid() { + Matrix3 a = Data3Rigid; + CORRADE_BENCHMARK(Repeats) { + a = a.invertedRigid(); + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::invert3Orthogonal() { + Matrix3 a = Data3Orthogonal; + CORRADE_BENCHMARK(Repeats) { + a = a.invertedOrthogonal(); + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::invert4() { + Matrix4 a = Data4; + CORRADE_BENCHMARK(Repeats) { + a = a.inverted(); + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::invert4GaussJordan() { + Matrix4 a = Data4; + CORRADE_BENCHMARK(Repeats) { + a = Math::Algorithms::gaussJordanInverted(a); + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::invert4Rigid() { + Matrix4 a = Data4Rigid; + CORRADE_BENCHMARK(Repeats) { + a = a.invertedRigid(); + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::invert4Orthogonal() { + Matrix4 a = Data4Orthogonal; + CORRADE_BENCHMARK(Repeats) { + a = a.invertedOrthogonal(); + } + + CORRADE_VERIFY(a.toVector().sum() != 0); +} + +void MatrixBenchmark::transformVector3() { + Vector2 a{3.0f, -2.2f}; + CORRADE_BENCHMARK(Repeats) { + a = Data3.transformVector(a); + } + + CORRADE_VERIFY(a.sum() != 0); +} + +void MatrixBenchmark::transformPoint3() { + Vector2 a{3.0f, -2.2f}; + CORRADE_BENCHMARK(Repeats) { + a = Data3.transformPoint(a); + } + + CORRADE_VERIFY(a.sum() != 0); +} + +void MatrixBenchmark::transformVector4() { + Vector3 a{1.0f, 3.0f, -2.2f}; + CORRADE_BENCHMARK(Repeats) { + a = Data4.transformVector(a); + } + + CORRADE_VERIFY(a.sum() != 0); +} + +void MatrixBenchmark::transformPoint4() { + Vector3 a{1.0f, 3.0f, -2.2f}; + CORRADE_BENCHMARK(Repeats) { + a = Data4.transformVector(a); + } + + CORRADE_VERIFY(a.sum() != 0); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::MatrixBenchmark)