jaulib v1.3.6
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
144std::ostream& operator<<(std::ostream& out, const AABBox& v) noexcept {
145 return out << "aabb[bl " << v.lo << ", tr " << v.hi << "]";
146}
147
148#include <random>
149
150TEST_CASE( "Int Math Bench 04a", "[intersect][benchmark][arithmetic][math]" ) {
151 std::mt19937 rng;
152 int32_t seed_val=0;
153 rng.seed(seed_val);
154 std::uniform_int_distribution<int32_t> rint(0,50);
155
156 const int loops = catch_auto_run ? 1000 : 1000000;
157 size_t isect_count=0;
158 std::vector<AABBox> va, vb;
159 for(int i=0; i<loops; ++i) {
160 Point2i lo(rint(rng), rint(rng));
161 Point2i hi(lo.x+rint(rng), lo.y+rint(rng));
162 AABBox a { lo, hi };
163 lo = Point2i(rint(rng), rint(rng));
164 hi = Point2i(lo.x+rint(rng), lo.y+rint(rng));
165 AABBox b { lo, hi };
166 va.push_back(a);
167 vb.push_back(b);
168 bool i1a = a.intersects1a(b);
169 bool i1b = a.intersects1b(b);
170 bool i1c = a.intersects1c(b);
171 if( i1a ) {
172 ++isect_count;
173 }
174 // std::cout << "# " << i << std::endl;
175 // std::cout << "A: " << a << std::endl;
176 // std::cout << "B: " << b << ", i " << i1a << std::endl;
177 REQUIRE( i1a == i1b );
178 REQUIRE( i1a == i1c );
179 // std::cout << std::endl;
180 bool i2a = a.intersects2a(b);
181 bool i2b = a.intersects2b(b);
182 bool i2c = a.intersects2c(b);
183 REQUIRE( i1a == i2a );
184 REQUIRE( i2a == i2b );
185 REQUIRE( i2a == i2c );
186 }
187 std::cout << "isect_count " << isect_count << "/" << va.size() << ", " << 100.0f*( (float)isect_count / (float)va.size() ) << "%" << std::endl;
188
189 BENCHMARK("Intersect1a Benchmark") {
190 size_t r = 0;
191 for(size_t i = 0; i < va.size(); ++i) {
192 AABBox a = va[i];
193 AABBox b = vb[i];
194 r += a.intersects1a(b) ? 10 : 1;
195 }
196 return r;
197 };
198 BENCHMARK("Intersect1b Benchmark") {
199 size_t r = 0;
200 for(size_t i = 0; i < va.size(); ++i) {
201 AABBox a = va[i];
202 AABBox b = vb[i];
203 r += a.intersects1b(b) ? 10 : 1;
204 }
205 return r;
206 };
207 BENCHMARK("Intersect1c Benchmark") {
208 size_t r = 0;
209 for(size_t i = 0; i < va.size(); ++i) {
210 AABBox a = va[i];
211 AABBox b = vb[i];
212 r += a.intersects1c(b) ? 10 : 1;
213 }
214 return r;
215 };
216 BENCHMARK("Intersect2a Benchmark") {
217 size_t r = 0;
218 for(size_t i = 0; i < va.size(); ++i) {
219 AABBox a = va[i];
220 AABBox b = vb[i];
221 r += a.intersects2a(b) ? 10 : 1;
222 }
223 return r;
224 };
225 BENCHMARK("Intersect2b Benchmark") {
226 size_t r = 0;
227 for(size_t i = 0; i < va.size(); ++i) {
228 AABBox a = va[i];
229 AABBox b = vb[i];
230 r += a.intersects2b(b) ? 10 : 1;
231 }
232 return r;
233 };
234 BENCHMARK("Intersect2c Benchmark") {
235 size_t r = 0;
236 for(size_t i = 0; i < va.size(); ++i) {
237 AABBox a = va[i];
238 AABBox b = vb[i];
239 r += a.intersects2c(b) ? 10 : 1;
240 }
241 return r;
242 };
243}
244
value_type x
Definition vec2i.hpp:77
value_type y
Definition vec2i.hpp:78
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 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...
std::ostream & operator<<(std::ostream &out, const cow_darray< Value_type, Size_type, Alloc_type > &c)
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:314
__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