aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Romanko <me@blankhex.com>2025-10-12 23:16:00 +0300
committerMikhail Romanko <me@blankhex.com>2025-10-12 23:16:00 +0300
commit577c3091e6db9719f6528cf5508c33b3f2038c48 (patch)
treea0ca32cfed53c9562ec55de1955667dcb393fb5e
parent54563daf13befd1c0b5583f886d6ea60c12253ef (diff)
downloadbhlib-577c3091e6db9719f6528cf5508c33b3f2038c48.tar.gz
Add LTO in configure, add more benchmarks
-rw-r--r--bench/include/BH/Bench.h16
-rw-r--r--bench/src/Bench.c2
-rw-r--r--bench/tests/BenchBox2f.c80
-rw-r--r--bench/tests/BenchBox3f.c82
-rw-r--r--bench/tests/BenchLine.c55
-rw-r--r--bench/tests/BenchPlane.c57
-rw-r--r--bench/tests/BenchVec.c139
-rw-r--r--bench/tests/BenchVec2f.c204
-rw-r--r--bench/tests/BenchVec2i.c107
-rw-r--r--bench/tests/BenchVec3f.c202
-rw-r--r--bench/tests/BenchVec3i.c108
-rw-r--r--bench/tests/BenchVec4f.c191
-rw-r--r--bench/tests/BenchVec4i.c108
-rwxr-xr-xconfigure12
14 files changed, 1222 insertions, 141 deletions
diff --git a/bench/include/BH/Bench.h b/bench/include/BH/Bench.h
index 61a7778..6bf322b 100644
--- a/bench/include/BH/Bench.h
+++ b/bench/include/BH/Bench.h
@@ -1,6 +1,7 @@
#ifndef BH_BENCH_H
#define BH_BENCH_H
+
typedef struct BH_Bench BH_Bench;
typedef void (*BH_BenchCallback)(BH_Bench *);
@@ -22,4 +23,19 @@ int BH_BenchIter(BH_Bench *state);
int BH_BenchRun(void);
+
+#if defined(__GNUC__) || defined(__clang__)
+#define BH_BenchDoNotOptimize(arg) \
+ do { \
+ __asm__ __volatile__("" : : "r"(*((char volatile*) &arg)) : "memory"); \
+ } while (0)
+#else
+ #define BH_BenchDoNotOptimize(arg) \
+ do { \
+ volatile void* _ptr = (void*)&(arg); \
+ (void)_ptr; \
+ } while (0)
+#endif
+
+
#endif /* BH_BENCH_H */
diff --git a/bench/src/Bench.c b/bench/src/Bench.c
index 07d3236..79a4e10 100644
--- a/bench/src/Bench.c
+++ b/bench/src/Bench.c
@@ -86,7 +86,7 @@ int BH_BenchIter(BH_Bench *state)
float ips, ns;
ips = state->iterations / (millis / 1000.0f);
ns = (millis * 1000000.0) / state->iterations;
- printf("%s\t%.2f ips (%.2f ns)\n", state->name, ips, ns);
+ printf("%-12s %.2f ips (%.2f ns)\n", state->name, ips, ns);
return 0;
}
return 1;
diff --git a/bench/tests/BenchBox2f.c b/bench/tests/BenchBox2f.c
new file mode 100644
index 0000000..34f0aa6
--- /dev/null
+++ b/bench/tests/BenchBox2f.c
@@ -0,0 +1,80 @@
+#include "BH/Bench.h"
+#include "BH/Math/Box2f.h"
+
+
+
+static float boxAMin[2] = {1.0f, 2.0f};
+static float boxAMax[2] = {5.0f, 6.0f};
+static float boxBMin[2] = {3.0f, 4.0f};
+static float boxBMax[2] = {7.0f, 8.0f};
+static float pointInside[2] = {3.0f, 4.0f};
+static float pointList[] =
+{
+ 1.0f, 2.0f,
+ 4.0f, 6.0f,
+ 2.0f, 3.0f,
+ 5.0f, 1.0f,
+ 3.0f, 7.0f
+};
+static size_t pointCount = 5;
+static float outMin[2];
+static float outMax[2];
+
+
+BH_BENCH_TEST(Union)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Box2fUnion(boxAMin, boxAMax, boxBMin, boxBMax, outMin, outMax);
+ BH_BenchDoNotOptimize(outMin);
+ BH_BenchDoNotOptimize(outMax);
+ }
+}
+
+
+BH_BENCH_TEST(Intersect)
+{
+ while (BH_BenchIter(state))
+ {
+ int result;
+ result = BH_Box2fIntersect(boxAMin, boxAMax, boxBMin, boxBMax, outMin, outMax);
+ BH_BenchDoNotOptimize(result);
+ BH_BenchDoNotOptimize(outMin);
+ BH_BenchDoNotOptimize(outMax);
+ }
+}
+
+
+BH_BENCH_TEST(Contains)
+{
+ while (BH_BenchIter(state))
+ {
+ int result;
+ result = BH_Box2fContains(boxAMin, boxAMax, pointInside);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Enclose)
+{
+ while (BH_BenchIter(state))
+ {
+ int result;
+ result = BH_Box2fEnclose(pointList, pointCount, outMin, outMax);
+ BH_BenchDoNotOptimize(result);
+ BH_BenchDoNotOptimize(outMin);
+ BH_BenchDoNotOptimize(outMax);
+ }
+}
+
+
+int main(void)
+{
+ BH_BENCH_ADD(Union);
+ BH_BENCH_ADD(Intersect);
+ BH_BENCH_ADD(Contains);
+ BH_BENCH_ADD(Enclose);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchBox3f.c b/bench/tests/BenchBox3f.c
new file mode 100644
index 0000000..08d9713
--- /dev/null
+++ b/bench/tests/BenchBox3f.c
@@ -0,0 +1,82 @@
+#include "BH/Bench.h"
+#include "BH/Math/Box3f.h"
+
+
+static float boxAMin[3] = {1.0f, 2.0f, 3.0f};
+static float boxAMax[3] = {6.0f, 7.0f, 8.0f};
+static float boxBMin[3] = {4.0f, 5.0f, 2.0f};
+static float boxBMax[3] = {9.0f, 10.0f, 6.0f};
+static float pointInside[3] = {3.0f, 4.0f, 5.0f};
+static float pointList[] =
+{
+ 1.0f, 2.0f, 3.0f,
+ 5.0f, 1.0f, 7.0f,
+ 2.0f, 6.0f, 4.0f,
+ 8.0f, 3.0f, 5.0f,
+ 4.0f, 4.0f, 1.0f
+};
+static size_t pointCount = 5;
+static float outMin[3];
+static float outMax[3];
+
+
+BH_BENCH_TEST(Union)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Box3fUnion(boxAMin, boxAMax, boxBMin, boxBMax, outMin, outMax);
+ BH_BenchDoNotOptimize(outMin);
+ BH_BenchDoNotOptimize(outMax);
+ }
+}
+
+
+BH_BENCH_TEST(Intersect)
+{
+ while (BH_BenchIter(state))
+ {
+ int result;
+ result = BH_Box3fIntersect(boxAMin, boxAMax, boxBMin, boxBMax, outMin, outMax);
+ BH_BenchDoNotOptimize(result);
+ BH_BenchDoNotOptimize(outMin);
+ BH_BenchDoNotOptimize(outMax);
+ }
+}
+
+
+BH_BENCH_TEST(Contains)
+{
+ while (BH_BenchIter(state))
+ {
+ int result;
+ result = BH_Box3fContains(boxAMin, boxAMax, pointInside);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Enclose)
+{
+ while (BH_BenchIter(state))
+ {
+ int result;
+ result = BH_Box3fEnclose(pointList, pointCount, outMin, outMax);
+ BH_BenchDoNotOptimize(result);
+ BH_BenchDoNotOptimize(outMin);
+ BH_BenchDoNotOptimize(outMax);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(Union);
+ BH_BENCH_ADD(Intersect);
+ BH_BENCH_ADD(Contains);
+ BH_BENCH_ADD(Enclose);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchLine.c b/bench/tests/BenchLine.c
new file mode 100644
index 0000000..bbef886
--- /dev/null
+++ b/bench/tests/BenchLine.c
@@ -0,0 +1,55 @@
+#include "BH/Bench.h"
+#include "BH/Math/Line.h"
+
+
+static float pointA[2] = {1.0f, 2.0f};
+static float pointB[2] = {4.0f, 6.0f};
+static float lineNormal[3] = {3.0f, -4.0f, 5.0f};
+static float outLine[3];
+static float outPoint[2];
+
+
+BH_BENCH_TEST(FromPoints)
+{
+ while (BH_BenchIter(state))
+ {
+ int result;
+ result = BH_LineFromPoints(pointA, pointB, outLine);
+ BH_BenchDoNotOptimize(result);
+ BH_BenchDoNotOptimize(outLine);
+ }
+}
+
+
+BH_BENCH_TEST(Distance)
+{
+ while (BH_BenchIter(state))
+ {
+ float result;
+ result = BH_LineDistance(lineNormal, pointA);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(ClosestPoint)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_LineClosestPoint(lineNormal, pointA, outPoint);
+ BH_BenchDoNotOptimize(outPoint);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(FromPoints);
+ BH_BENCH_ADD(Distance);
+ BH_BENCH_ADD(ClosestPoint);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchPlane.c b/bench/tests/BenchPlane.c
new file mode 100644
index 0000000..4c5a115
--- /dev/null
+++ b/bench/tests/BenchPlane.c
@@ -0,0 +1,57 @@
+#include "BH/Bench.h"
+#include "BH/Math/Plane.h"
+
+
+static float pointA[3] = {1.0f, 2.0f, 3.0f};
+static float pointB[3] = {4.0f, 6.0f, 2.0f};
+static float pointC[3] = {2.0f, 1.0f, -1.0f};
+static float testPoint[3] = {5.0f, -3.0f, 7.0f};
+static float planeNormal[4] = {1.0f, -2.0f, 1.0f, 4.0f};
+static float outPlane[4];
+static float outPoint[3];
+
+
+BH_BENCH_TEST(FromPoints)
+{
+ while (BH_BenchIter(state))
+ {
+ int result;
+ result = BH_PlaneFromPoints(pointA, pointB, pointC, outPlane);
+ BH_BenchDoNotOptimize(result);
+ BH_BenchDoNotOptimize(outPlane);
+ }
+}
+
+
+BH_BENCH_TEST(Distance)
+{
+ while (BH_BenchIter(state))
+ {
+ float result;
+ result = BH_PlaneDistance(planeNormal, testPoint);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(ClosestPoint)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_PlaneClosestPoint(planeNormal, testPoint, outPoint);
+ BH_BenchDoNotOptimize(outPoint);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(FromPoints);
+ BH_BENCH_ADD(Distance);
+ BH_BENCH_ADD(ClosestPoint);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchVec.c b/bench/tests/BenchVec.c
deleted file mode 100644
index e760748..0000000
--- a/bench/tests/BenchVec.c
+++ /dev/null
@@ -1,139 +0,0 @@
-#include <BH/Bench.h>
-
-#include <BH/Math/Vec2i.h>
-#include <BH/Math/Vec3i.h>
-#include <BH/Math/Vec4i.h>
-#include <BH/Math/Vec2f.h>
-#include <BH/Math/Vec3f.h>
-#include <BH/Math/Vec4f.h>
-#include <stdlib.h>
-
-
-BH_BENCH_TEST(Vec2i)
-{
- int a[2], b[2];
-
- a[0] = (rand() % 100);
- a[1] = (rand() % 100);
-
- b[0] = (rand() % 100);
- b[1] = (rand() % 100);
-
- while (BH_BenchIter(state))
- {
- BH_Vec2iAdd(a, b, a);
- }
-}
-
-
-BH_BENCH_TEST(Vec3i)
-{
- int a[3], b[3];
-
- a[0] = (rand() % 100);
- a[1] = (rand() % 100);
- a[2] = (rand() % 100);
-
- b[0] = (rand() % 100);
- b[1] = (rand() % 100);
- b[2] = (rand() % 100);
-
- while (BH_BenchIter(state))
- {
- BH_Vec3iAdd(a, b, a);
- }
-}
-
-
-BH_BENCH_TEST(Vec4i)
-{
- int a[4], b[4];
-
- a[0] = (rand() % 100);
- a[1] = (rand() % 100);
- a[2] = (rand() % 100);
- a[3] = (rand() % 100);
-
- b[0] = (rand() % 100);
- b[1] = (rand() % 100);
- b[2] = (rand() % 100);
- b[3] = (rand() % 100);
-
- while (BH_BenchIter(state))
- {
- BH_Vec4iAdd(a, b, a);
- }
-}
-
-
-BH_BENCH_TEST(Vec2f)
-{
- float a[2], b[2];
-
- a[0] = (rand() % 100) / 200.0;
- a[1] = (rand() % 100) / 200.0;
-
- b[0] = (rand() % 100) / 200.0;
- b[1] = (rand() % 100) / 200.0;
-
- while (BH_BenchIter(state))
- {
- BH_Vec2fAdd(a, b, a);
- }
-}
-
-
-BH_BENCH_TEST(Vec3f)
-{
- float a[3], b[3];
-
- a[0] = (rand() % 100) / 200.0;
- a[1] = (rand() % 100) / 200.0;
- a[2] = (rand() % 100) / 200.0;
-
- b[0] = (rand() % 100) / 200.0;
- b[1] = (rand() % 100) / 200.0;
- b[2] = (rand() % 100) / 200.0;
-
- while (BH_BenchIter(state))
- {
- BH_Vec3fAdd(a, b, a);
- }
-}
-
-
-BH_BENCH_TEST(Vec4f)
-{
- float a[4], b[4];
-
- a[0] = (rand() % 100) / 200.0;
- a[1] = (rand() % 100) / 200.0;
- a[2] = (rand() % 100) / 200.0;
- a[3] = (rand() % 100) / 200.0;
-
- b[0] = (rand() % 100) / 200.0;
- b[1] = (rand() % 100) / 200.0;
- b[2] = (rand() % 100) / 200.0;
- b[3] = (rand() % 100) / 200.0;
-
- while (BH_BenchIter(state))
- {
- BH_Vec4fAdd(a, b, a);
- }
-}
-
-
-int main(int argc, char **argv)
-{
- BH_UNUSED(argc);
- BH_UNUSED(argv);
-
- BH_BENCH_ADD(Vec2i);
- BH_BENCH_ADD(Vec3i);
- BH_BENCH_ADD(Vec4i);
- BH_BENCH_ADD(Vec2f);
- BH_BENCH_ADD(Vec3f);
- BH_BENCH_ADD(Vec4f);
-
- return BH_BenchRun();
-}
diff --git a/bench/tests/BenchVec2f.c b/bench/tests/BenchVec2f.c
new file mode 100644
index 0000000..a180bd7
--- /dev/null
+++ b/bench/tests/BenchVec2f.c
@@ -0,0 +1,204 @@
+#include "BH/Bench.h"
+#include "BH/Math/Vec2f.h"
+
+
+static float vecA[2] = {1.0f, 2.0f};
+static float vecB[2] = {3.0f, -1.0f};
+static float vecC[2] = {0.5f, 4.0f};
+static float vecZero[2] = {0.0f, 0.0f};
+static float vecLarge[2] = {1e6f, -1e6f};
+static float vecOut[2];
+
+
+BH_BENCH_TEST(Add)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fAdd(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Sub)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fSub(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Mul)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fMul(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Scale)
+{
+ const float scale = 2.5f;
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fScale(vecA, scale, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(MulAdd)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fMulAdd(vecA, vecB, vecC, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Negate)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fNegate(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Dot)
+{
+ float result;
+ while (BH_BenchIter(state))
+ {
+ result = BH_Vec2fDot(vecA, vecB);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Cross)
+{
+ float result;
+ while (BH_BenchIter(state))
+ {
+ result = BH_Vec2fCross(vecA, vecB);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Length)
+{
+ float result;
+ while (BH_BenchIter(state))
+ {
+ result = BH_Vec2fLength(vecA);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Normal)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fNormal(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(NormalEx)
+{
+ float length;
+ while (BH_BenchIter(state))
+ {
+ length = BH_Vec2fNormalEx(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ BH_BenchDoNotOptimize(length);
+ }
+}
+
+
+BH_BENCH_TEST(Min)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fMin(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Max)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fMax(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Lerp)
+{
+ const float t = 0.3f;
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fLerp(vecA, vecB, t, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Project)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fProject(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Barycentric)
+{
+ const float v = 0.2f, w = 0.3f;
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2fBarycentric(vecA, vecB, vecC, v, w, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(Add);
+ BH_BENCH_ADD(Sub);
+ BH_BENCH_ADD(Mul);
+ BH_BENCH_ADD(Scale);
+ BH_BENCH_ADD(MulAdd);
+ BH_BENCH_ADD(Negate);
+ BH_BENCH_ADD(Dot);
+ BH_BENCH_ADD(Cross);
+ BH_BENCH_ADD(Length);
+ BH_BENCH_ADD(Normal);
+ BH_BENCH_ADD(NormalEx);
+ BH_BENCH_ADD(Min);
+ BH_BENCH_ADD(Max);
+ BH_BENCH_ADD(Lerp);
+ BH_BENCH_ADD(Project);
+ BH_BENCH_ADD(Barycentric);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchVec2i.c b/bench/tests/BenchVec2i.c
new file mode 100644
index 0000000..945a9c5
--- /dev/null
+++ b/bench/tests/BenchVec2i.c
@@ -0,0 +1,107 @@
+#include "BH/Bench.h"
+#include "BH/Math/Vec2i.h"
+
+
+static int vecA[2] = {5, -3};
+static int vecB[2] = {2, 7};
+static int vecC[2] = {4, 1};
+static int vecOut[2];
+
+
+BH_BENCH_TEST(Add)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2iAdd(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Sub)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2iSub(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Mul)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2iMul(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Scale)
+{
+ const int s = 3;
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2iScale(vecA, s, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(MulAdd)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2iMulAdd(vecA, vecB, vecC, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Negate)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2iNegate(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Min)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2iMin(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Max)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec2iMax(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(Add);
+ BH_BENCH_ADD(Sub);
+ BH_BENCH_ADD(Mul);
+ BH_BENCH_ADD(Scale);
+ BH_BENCH_ADD(MulAdd);
+ BH_BENCH_ADD(Negate);
+ BH_BENCH_ADD(Min);
+ BH_BENCH_ADD(Max);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchVec3f.c b/bench/tests/BenchVec3f.c
new file mode 100644
index 0000000..5908626
--- /dev/null
+++ b/bench/tests/BenchVec3f.c
@@ -0,0 +1,202 @@
+#include "BH/Bench.h"
+#include "BH/Math/Vec3f.h"
+
+
+static float vecA[3] = {1.0f, 2.0f, 3.0f};
+static float vecB[3] = {4.0f, -1.0f, 0.5f};
+static float vecC[3] = {0.5f, 0.5f, 2.0f};
+static float vecOut[3];
+
+
+BH_BENCH_TEST(Add)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fAdd(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Sub)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fSub(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Mul)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fMul(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Scale)
+{
+ static float scalar = 2.5f;
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fScale(vecA, scalar, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(MulAdd)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fMulAdd(vecA, vecB, vecC, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Negate)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fNegate(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Dot)
+{
+ float result;
+ while (BH_BenchIter(state))
+ {
+ result = BH_Vec3fDot(vecA, vecB);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Cross)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fCross(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Length)
+{
+ float result;
+ while (BH_BenchIter(state))
+ {
+ result = BH_Vec3fLength(vecA);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Normal)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fNormal(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(NormalEx)
+{
+ float result;
+ while (BH_BenchIter(state))
+ {
+ result = BH_Vec3fNormalEx(vecA, vecOut);
+ BH_BenchDoNotOptimize(result);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Min)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fMin(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Max)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fMax(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Lerp)
+{
+ static float t = 0.75f;
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fLerp(vecA, vecB, t, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Project)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fProject(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Barycentric)
+{
+ static float v = 0.3f;
+ static float w = 0.4f;
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3fBarycentric(vecA, vecB, vecC, v, w, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(Add);
+ BH_BENCH_ADD(Sub);
+ BH_BENCH_ADD(Mul);
+ BH_BENCH_ADD(Scale);
+ BH_BENCH_ADD(MulAdd);
+ BH_BENCH_ADD(Negate);
+ BH_BENCH_ADD(Dot);
+ BH_BENCH_ADD(Cross);
+ BH_BENCH_ADD(Length);
+ BH_BENCH_ADD(Normal);
+ BH_BENCH_ADD(NormalEx);
+ BH_BENCH_ADD(Min);
+ BH_BENCH_ADD(Max);
+ BH_BENCH_ADD(Lerp);
+ BH_BENCH_ADD(Project);
+ BH_BENCH_ADD(Barycentric);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchVec3i.c b/bench/tests/BenchVec3i.c
new file mode 100644
index 0000000..8e356f3
--- /dev/null
+++ b/bench/tests/BenchVec3i.c
@@ -0,0 +1,108 @@
+#include "BH/Bench.h"
+#include "BH/Math/Vec3i.h"
+
+
+static int vecA[3] = {1, 2, 3};
+static int vecB[3] = {4, -1, 5};
+static int vecC[3] = {2, 3, -1};
+static int vecOut[3];
+
+
+BH_BENCH_TEST(Add)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3iAdd(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Sub)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3iSub(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Mul)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3iMul(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Scale)
+{
+ int scalar = 3;
+
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3iScale(vecA, scalar, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(MulAdd)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3iMulAdd(vecA, vecB, vecC, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Negate)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3iNegate(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Min)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3iMin(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Max)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec3iMax(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(Add);
+ BH_BENCH_ADD(Sub);
+ BH_BENCH_ADD(Mul);
+ BH_BENCH_ADD(Scale);
+ BH_BENCH_ADD(MulAdd);
+ BH_BENCH_ADD(Negate);
+ BH_BENCH_ADD(Min);
+ BH_BENCH_ADD(Max);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchVec4f.c b/bench/tests/BenchVec4f.c
new file mode 100644
index 0000000..c7aebb3
--- /dev/null
+++ b/bench/tests/BenchVec4f.c
@@ -0,0 +1,191 @@
+#include "BH/Bench.h"
+#include "BH/Math/Vec4f.h"
+
+
+static float vecA[4] = {1.0f, 2.0f, 3.0f, 4.0f};
+static float vecB[4] = {4.0f, -1.0f, 0.5f, 2.0f};
+static float vecC[4] = {0.5f, 0.5f, 2.0f, 1.0f};
+static float vecOut[4];
+
+
+BH_BENCH_TEST(Add)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fAdd(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Sub)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fSub(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Mul)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fMul(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Scale)
+{
+ float scalar = 2.5f;
+
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fScale(vecA, scalar, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(MulAdd)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fMulAdd(vecA, vecB, vecC, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Negate)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fNegate(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Dot)
+{
+ while (BH_BenchIter(state))
+ {
+ float result = BH_Vec4fDot(vecA, vecB);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Length)
+{
+ while (BH_BenchIter(state))
+ {
+ float result = BH_Vec4fLength(vecA);
+ BH_BenchDoNotOptimize(result);
+ }
+}
+
+
+BH_BENCH_TEST(Normal)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fNormal(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(NormalEx)
+{
+ while (BH_BenchIter(state))
+ {
+ float result = BH_Vec4fNormalEx(vecA, vecOut);
+ BH_BenchDoNotOptimize(result);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Min)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fMin(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Max)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fMax(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Lerp)
+{
+ float t = 0.75f;
+
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fLerp(vecA, vecB, t, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Project)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fProject(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Barycentric)
+{
+ float v = 0.3f;
+ float w = 0.4f;
+
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4fBarycentric(vecA, vecB, vecC, v, w, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(Add);
+ BH_BENCH_ADD(Sub);
+ BH_BENCH_ADD(Mul);
+ BH_BENCH_ADD(Scale);
+ BH_BENCH_ADD(MulAdd);
+ BH_BENCH_ADD(Negate);
+ BH_BENCH_ADD(Dot);
+ BH_BENCH_ADD(Length);
+ BH_BENCH_ADD(Normal);
+ BH_BENCH_ADD(NormalEx);
+ BH_BENCH_ADD(Min);
+ BH_BENCH_ADD(Max);
+ BH_BENCH_ADD(Lerp);
+ BH_BENCH_ADD(Project);
+ BH_BENCH_ADD(Barycentric);
+
+ return BH_BenchRun();
+}
diff --git a/bench/tests/BenchVec4i.c b/bench/tests/BenchVec4i.c
new file mode 100644
index 0000000..56ceb42
--- /dev/null
+++ b/bench/tests/BenchVec4i.c
@@ -0,0 +1,108 @@
+#include "BH/Bench.h"
+#include "BH/Math/Vec4i.h"
+
+
+static int vecA[4] = {1, 2, 3, 4};
+static int vecB[4] = {4, -1, 5, 2};
+static int vecC[4] = {2, 3, -1, 1};
+static int vecOut[4];
+
+
+BH_BENCH_TEST(Add)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4iAdd(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Sub)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4iSub(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Mul)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4iMul(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Scale)
+{
+ int scalar = 3;
+
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4iScale(vecA, scalar, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(MulAdd)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4iMulAdd(vecA, vecB, vecC, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Negate)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4iNegate(vecA, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Min)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4iMin(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+BH_BENCH_TEST(Max)
+{
+ while (BH_BenchIter(state))
+ {
+ BH_Vec4iMax(vecA, vecB, vecOut);
+ BH_BenchDoNotOptimize(vecOut);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ BH_UNUSED(argc);
+ BH_UNUSED(argv);
+
+ BH_BENCH_ADD(Add);
+ BH_BENCH_ADD(Sub);
+ BH_BENCH_ADD(Mul);
+ BH_BENCH_ADD(Scale);
+ BH_BENCH_ADD(MulAdd);
+ BH_BENCH_ADD(Negate);
+ BH_BENCH_ADD(Min);
+ BH_BENCH_ADD(Max);
+
+ return BH_BenchRun();
+}
diff --git a/configure b/configure
index 55d21cf..eb1138d 100755
--- a/configure
+++ b/configure
@@ -13,6 +13,7 @@ enable_lfs="no"
enable_tests="yes"
enable_benchmarks="no"
enable_pic="yes"
+enable_lto="no"
use_clock_gettime="no"
use_short_limbs="no"
arflags=${ARFLAGS:-cr}
@@ -57,8 +58,10 @@ for option do
--use-short-limbs|--use-short-limbs=yes) use_short_limbs="yes" ;;
--use-short-limbs=no) use_short_limbs="no" ;;
--source=*) source_path="${option#--source=}" ;;
- --enable-pic|--with-pic=yes) enable_pic="yes" ;;
+ --enable-pic|--enable-pic=yes) enable_pic="yes" ;;
--enable-pic=no) enable_pic="no" ;;
+ --enable-lto|--enable-lto=yes) enable_lto="yes" ;;
+ --enable-lto=no) enable_lto="no" ;;
--help|-h) display_help="yes" ;;
*) echo "configure: WARNING unrecognized option $option" ;;
esac
@@ -86,6 +89,7 @@ Options:
--prefix= Install prefix
--enable-shared[=yes|no] Make shared library
--enable-pic[=yes|no] Enable position independent code (PIC)
+ --enable-lto[=yes|no] Enable link time optimizations
--enable-mt[=yes|no] Enable multithreading support
--enable-lfs[=yes|no] Enable large file support
--enable-tests[=yes|no] Enable unit tests
@@ -136,6 +140,11 @@ if [ "$enable_pic" = "yes" ]; then
cflags="$cflags -fPIC"
fi
+if [ "$enable_lto" = "yes" ]; then
+ cflags="$cflags -flto"
+ ldflags="$ldflags -flto"
+fi
+
if [ "$enable_pic" = "no" ] && [ "$enable_shared" = "yes" ]; then
echo "configure: WARNING: requested shared library while PIC is disabled"
echo "configure: WARNING: expect build failure"
@@ -435,6 +444,7 @@ echo "Enable long file support: $enable_lfs"
echo "Enable tests: $enable_tests"
echo "Enable benchmarks: $enable_benchmarks"
echo "Enable PIC: $enable_pic"
+echo "Enable LTO: $enable_lto"
echo "Build shared library: $enable_shared"
echo "Use clock_gettime: $use_clock_gettime"
echo "Use short limbs: $use_short_limbs"