jaulib v1.4.1
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
test_int_math_perf01.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#include <cassert>
25#include <cstring>
26
27#include <jau/test/catch2_ext.hpp>
28
29#include <jau/int_math.hpp>
30#include <jau/math/vec2i.hpp>
31
32using namespace jau;
33using namespace jau::int_literals;
34
35TEST_CASE( "Int Math Bench 01a", "[abs][benchmark][arithmetic][math]" ) {
36 BENCHMARK("jau::abs Benchmark") {
37 REQUIRE( 1 == jau::abs( 1) );
38 REQUIRE( 1 == jau::abs(-1) );
39 REQUIRE( 1_i64 == jau::abs( 1_i64) );
40 REQUIRE( 1_i64 == jau::abs(-1_i64) );
41 REQUIRE( std::numeric_limits<int64_t>::max() == jau::abs( std::numeric_limits<int64_t>::max() ) );
42 REQUIRE( INT32_MAX == jau::abs( INT32_MAX ) );
43 };
44}
45TEST_CASE( "Int Math Bench 01b", "[ct_abs][benchmark][arithmetic][math]" ) {
46 BENCHMARK("jau::ct_abs Benchmark") {
47 REQUIRE( 1 == jau::ct_abs( 1) );
48 REQUIRE( 1 == jau::ct_abs(-1) );
49 REQUIRE( 1_i64 == jau::ct_abs( 1_i64) );
50 REQUIRE( 1_i64 == jau::ct_abs(-1_i64) );
51 REQUIRE( std::numeric_limits<int64_t>::max() == jau::ct_abs( std::numeric_limits<int64_t>::max() ) );
52 // REQUIRE( std::numeric_limits<int64_t>::max() == jau::ct_abs( std::numeric_limits<int64_t>::min() ) ); // UB
53 REQUIRE( INT32_MAX == jau::ct_abs( INT32_MAX ) );
54 // REQUIRE( INT32_MAX == jau::ct_abs( INT32_MIN ) ); // UB
55 };
56}
57TEST_CASE( "Int Math Bench 01c", "[abs][benchmark][arithmetic][math]" ) {
58 BENCHMARK("std::abs Benchmark") {
59 REQUIRE( 1 == std::abs( 1) );
60 REQUIRE( 1 == std::abs(-1) );
61 REQUIRE( 1_i64 == std::abs( 1_i64) );
62 REQUIRE( 1_i64 == std::abs(-1_i64) );
63 REQUIRE( std::numeric_limits<int64_t>::max() == std::abs( std::numeric_limits<int64_t>::max() ) );
64 REQUIRE( INT32_MAX == std::abs( INT32_MAX ) );
65 };
66}
67
68TEST_CASE( "Int Math Bench 02a", "[min][max][benchmark][arithmetic][math]" ) {
69 BENCHMARK("MinMax Benchmark") {
70 REQUIRE( 0 == jau::min( 0, INT32_MAX ) );
71 REQUIRE( INT32_MAX == jau::max( 0, INT32_MAX ) );
72 REQUIRE( INT32_MAX-1== jau::min( INT32_MAX-1, INT32_MAX ) );
73 REQUIRE( INT32_MAX == jau::max( INT32_MAX-1, INT32_MAX ) );
74 REQUIRE( INT32_MIN == jau::min( 0, INT32_MIN ) );
75 REQUIRE( 0 == jau::max( 0, INT32_MIN ) );
76 REQUIRE( INT32_MIN == jau::min( INT32_MIN+1, INT32_MIN ) );
77 REQUIRE( INT32_MIN+1== jau::max( INT32_MIN+1, INT32_MIN ) );
78 };
79}
80TEST_CASE( "Int Math Bench 03a", "[ct_min][ct_max][benchmark][arithmetic][math]" ) {
81 BENCHMARK("Min2Max2 Benchmark") {
82 REQUIRE( 0 == jau::ct_min( 0, INT32_MAX ) );
83 REQUIRE( INT32_MAX == jau::ct_max( 0, INT32_MAX ) );
84 REQUIRE( INT32_MAX-1== jau::ct_min( INT32_MAX-1, INT32_MAX ) );
85 REQUIRE( INT32_MAX == jau::ct_max( INT32_MAX-1, INT32_MAX ) );
86 REQUIRE( INT32_MIN+1 == jau::ct_min( 0, INT32_MIN+1 ) ); // limitation: `MIN <= x - y <= MAX`
87 REQUIRE( 0 == jau::ct_max( 0, INT32_MIN+1 ) ); // limitation: `MIN <= x - y <= MAX`
88 REQUIRE( INT32_MIN == jau::ct_min( INT32_MIN+1, INT32_MIN ) );
89 REQUIRE( INT32_MIN+1== jau::ct_max( INT32_MIN+1, INT32_MIN ) );
90 };
91}
92
93using namespace jau::math;
94
95struct AABBox {
97
98 bool __attribute__ ((noinline))
99 intersects1a(const AABBox& o) const
100 {
101 return hi.x >= o.lo.x &&
102 hi.y >= o.lo.y &&
103 lo.x <= o.hi.x &&
104 lo.y <= o.hi.y;
105 }
106 bool __attribute__ ((noinline))
107 intersects1b(const AABBox& o) const
108 {
109 return !( hi.x < o.lo.x ||
110 hi.y < o.lo.y ||
111 lo.x > o.hi.x ||
112 lo.y > o.hi.y );
113 }
114 bool __attribute__ ((noinline))
115 intersects1c(const AABBox& o) const
116 {
117 const Point2i lo_ = max(lo, o.lo);
118 const Point2i hi_ = min(hi, o.hi);
119 return lo_.x <= hi_.x && lo_.y <= hi_.y;
120 }
121
122 bool intersects2a(const AABBox& o) const
123 {
124 return hi.x >= o.lo.x &&
125 hi.y >= o.lo.y &&
126 lo.x <= o.hi.x &&
127 lo.y <= o.hi.y;
128 }
129 bool intersects2b(const AABBox& o) const
130 {
131 return !( hi.x < o.lo.x ||
132 hi.y < o.lo.y ||
133 lo.x > o.hi.x ||
134 lo.y > o.hi.y );
135 }
136 bool intersects2c(const AABBox& o) const
137 {
138 const Point2i lo_ = max(lo, o.lo);
139 const Point2i hi_ = min(hi, o.hi);
140 return lo_.x <= hi_.x && lo_.y <= hi_.y;
141 }
142};
143
144#include <random>
145
146TEST_CASE( "Int Math Bench 04a", "[intersect][benchmark][arithmetic][math]" ) {
147 std::mt19937 rng;
148 int32_t seed_val=0;
149 rng.seed(seed_val);
150 std::uniform_int_distribution<int32_t> rint(0,50);
151
152 const int loops = catch_auto_run ? 1000 : 1000000;
153 size_t isect_count=0;
154 std::vector<AABBox> va, vb;
155 for(int i=0; i<loops; ++i) {
156 Point2i lo(rint(rng), rint(rng));
157 Point2i hi(lo.x+rint(rng), lo.y+rint(rng));
158 AABBox a { .lo=lo, .hi=hi };
159 lo = Point2i(rint(rng), rint(rng));
160 hi = Point2i(lo.x+rint(rng), lo.y+rint(rng));
161 AABBox b { .lo=lo, .hi=hi };
162 va.push_back(a);
163 vb.push_back(b);
164 bool i1a = a.intersects1a(b);
165 bool i1b = a.intersects1b(b);
166 bool i1c = a.intersects1c(b);
167 if( i1a ) {
168 ++isect_count;
169 }
170 // std::cout << "# " << i << std::endl;
171 // std::cout << "A: " << a << std::endl;
172 // std::cout << "B: " << b << ", i " << i1a << std::endl;
173 REQUIRE( i1a == i1b );
174 REQUIRE( i1a == i1c );
175 // std::cout << std::endl;
176 bool i2a = a.intersects2a(b);
177 bool i2b = a.intersects2b(b);
178 bool i2c = a.intersects2c(b);
179 REQUIRE( i1a == i2a );
180 REQUIRE( i2a == i2b );
181 REQUIRE( i2a == i2c );
182 }
183 std::cout << "isect_count " << isect_count << "/" << va.size() << ", " << 100.0f*( (float)isect_count / (float)va.size() ) << "%" << std::endl;
184
185 BENCHMARK("Intersect1a Benchmark") {
186 size_t r = 0;
187 for(size_t i = 0; i < va.size(); ++i) {
188 AABBox a = va[i];
189 AABBox b = vb[i];
190 r += a.intersects1a(b) ? 10 : 1;
191 }
192 return r;
193 };
194 BENCHMARK("Intersect1b Benchmark") {
195 size_t r = 0;
196 for(size_t i = 0; i < va.size(); ++i) {
197 AABBox a = va[i];
198 AABBox b = vb[i];
199 r += a.intersects1b(b) ? 10 : 1;
200 }
201 return r;
202 };
203 BENCHMARK("Intersect1c Benchmark") {
204 size_t r = 0;
205 for(size_t i = 0; i < va.size(); ++i) {
206 AABBox a = va[i];
207 AABBox b = vb[i];
208 r += a.intersects1c(b) ? 10 : 1;
209 }
210 return r;
211 };
212 BENCHMARK("Intersect2a Benchmark") {
213 size_t r = 0;
214 for(size_t i = 0; i < va.size(); ++i) {
215 AABBox a = va[i];
216 AABBox b = vb[i];
217 r += a.intersects2a(b) ? 10 : 1;
218 }
219 return r;
220 };
221 BENCHMARK("Intersect2b Benchmark") {
222 size_t r = 0;
223 for(size_t i = 0; i < va.size(); ++i) {
224 AABBox a = va[i];
225 AABBox b = vb[i];
226 r += a.intersects2b(b) ? 10 : 1;
227 }
228 return r;
229 };
230 BENCHMARK("Intersect2c Benchmark") {
231 size_t r = 0;
232 for(size_t i = 0; i < va.size(); ++i) {
233 AABBox a = va[i];
234 AABBox b = vb[i];
235 r += a.intersects2c(b) ? 10 : 1;
236 }
237 return r;
238 };
239}
240
value_type y
Definition vec2i.hpp:64
value_type x
Definition vec2i.hpp:63
constexpr T ct_max(const T x, const T y) noexcept
Returns the maximum of two integrals for MIN <= x - y <= MAX (w/o branching) in O(1) and constant tim...
constexpr T ct_min(const T x, const T y) noexcept
Returns the minimum of two integrals for MIN <= x - y <= MAX (w/o branching) in O(1) and constant tim...
constexpr T ct_abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/o branching) in O(1) and constant time (CT),...
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
Point2I< int > Point2i
Definition vec2i.hpp:334
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
bool intersects1b(const AABBox &o) const
bool intersects2c(const AABBox &o) const
bool intersects1c(const AABBox &o) const
bool intersects2b(const AABBox &o) const
bool intersects1a(const AABBox &o) const
bool intersects2a(const AABBox &o) const
TEST_CASE("Int Math Bench 01a", "[abs][benchmark][arithmetic][math]")
static int loops