diff --git a/AK/SIMDMath.h b/AK/SIMDMath.h index ca0708858a..5356d184c5 100644 --- a/AK/SIMDMath.h +++ b/AK/SIMDMath.h @@ -66,6 +66,15 @@ ALWAYS_INLINE static f32x4 exp(f32x4 v) }; } +ALWAYS_INLINE static f32x4 exp_approximate(f32x4 v) +{ + static constexpr int number_of_iterations = 10; + auto result = 1.f + v / (1 << number_of_iterations); + for (int i = 0; i < number_of_iterations; ++i) + result *= result; + return result; +} + ALWAYS_INLINE static f32x4 sqrt(f32x4 v) { #if ARCH(x86_64) diff --git a/Tests/AK/CMakeLists.txt b/Tests/AK/CMakeLists.txt index 77a288d2ea..e26a38e41f 100644 --- a/Tests/AK/CMakeLists.txt +++ b/Tests/AK/CMakeLists.txt @@ -61,6 +61,7 @@ set(AK_TEST_SOURCES TestQuickSort.cpp TestRedBlackTree.cpp TestRefPtr.cpp + TestSIMD.cpp TestSinglyLinkedList.cpp TestSourceGenerator.cpp TestSourceLocation.cpp diff --git a/Tests/AK/TestSIMD.cpp b/Tests/AK/TestSIMD.cpp new file mode 100644 index 0000000000..251904cbf2 --- /dev/null +++ b/Tests/AK/TestSIMD.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, Jelle Raaijmakers + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +#include +#include + +TEST_CASE(exp) +{ + AK::SIMD::f32x4 v = { .2f, .4f, .6f, .8f }; + auto result = AK::SIMD::exp(v); + + EXPECT_APPROXIMATE(result[0], 1.22140276f); + EXPECT_APPROXIMATE(result[1], 1.49182470f); + EXPECT_APPROXIMATE(result[2], 1.82211880f); + EXPECT_APPROXIMATE(result[3], 2.22554093f); +} + +TEST_CASE(exp_approximate) +{ + AK::SIMD::f32x4 v = { .2f, .4f, .6f, .8f }; + auto result = AK::SIMD::exp_approximate(v); + constexpr float accuracy = .001f; + + EXPECT(fabsf(result[0] - 1.22140276f) <= accuracy); + EXPECT(fabsf(result[1] - 1.49182470f) <= accuracy); + EXPECT(fabsf(result[2] - 1.82211880f) <= accuracy); + EXPECT(fabsf(result[3] - 2.22554093f) <= accuracy); +}