Browse Source

SIMDRegister abs operation implemented

tags/2021-05-28
Zsolt Garamvolgyi Tom Poole 6 years ago
parent
commit
c3a8ea1ab6
2 changed files with 48 additions and 1 deletions
  1. +7
    -0
      modules/juce_dsp/containers/juce_SIMDRegister.h
  2. +41
    -1
      modules/juce_dsp/containers/juce_SIMDRegister_test.cpp

+ 7
- 0
modules/juce_dsp/containers/juce_SIMDRegister.h View File

@@ -328,6 +328,13 @@ struct SIMDRegister
/** Returns a scalar which is the sum of all elements of the receiver. */ /** Returns a scalar which is the sum of all elements of the receiver. */
inline ElementType sum() const noexcept { return CmplxOps::sum (value); } inline ElementType sum() const noexcept { return CmplxOps::sum (value); }
//==============================================================================
/** Returns the absolute value of each element. */
static inline SIMDRegister JUCE_VECTOR_CALLTYPE abs (SIMDRegister a) noexcept
{
return a - (a * (expand (ElementType (2)) & lessThan (a, expand (ElementType (0)))));
}
//============================================================================== //==============================================================================
/** Checks if the given pointer is suffeciently aligned for using SIMD operations. */ /** Checks if the given pointer is suffeciently aligned for using SIMD operations. */
static inline bool isSIMDAligned (const ElementType* ptr) noexcept static inline bool isSIMDAligned (const ElementType* ptr) noexcept


+ 41
- 1
modules/juce_dsp/containers/juce_SIMDRegister_test.cpp View File

@@ -90,7 +90,7 @@ namespace SIMDRegister_test_internal
template <typename type> template <typename type>
struct VecFiller<SIMDRegister<type>> struct VecFiller<SIMDRegister<type>>
{ {
static SIMDRegister<type> fill(Random& random)
static SIMDRegister<type> fill (Random& random)
{ {
constexpr int size = (int) SIMDRegister<type>::SIMDNumElements; constexpr int size = (int) SIMDRegister<type>::SIMDNumElements;
#ifdef _MSC_VER #ifdef _MSC_VER
@@ -735,6 +735,29 @@ public:
} }
}; };
struct CheckAbs
{
template <typename type>
static void run (UnitTest& u, Random& random)
{
type inArray[SIMDRegister<type>::SIMDNumElements];
type outArray[SIMDRegister<type>::SIMDNumElements];
SIMDRegister_test_internal::VecFiller<type>::fill (inArray, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister<type> a;
copy (a, inArray);
a = SIMDRegister<type>::abs (a);
auto calcAbs = [] (type x) -> type { return x >= type (0) ? x : -x; };
for (size_t j = 0; j < SIMDRegister<type>::SIMDNumElements; ++j)
outArray[j] = calcAbs (inArray[j]);
u.expect (vecEqualToArray (a, outArray));
}
};
struct CheckBoolEquals struct CheckBoolEquals
{ {
template <typename type> template <typename type>
@@ -813,6 +836,21 @@ public:
TheTest::template run<uint64_t>(*this, random); TheTest::template run<uint64_t>(*this, random);
} }
template <class TheTest>
void runTestSigned (const char* unitTestName)
{
beginTest (unitTestName);
Random random = getRandom();
TheTest::template run<float> (*this, random);
TheTest::template run<double> (*this, random);
TheTest::template run<int8_t> (*this, random);
TheTest::template run<int16_t> (*this, random);
TheTest::template run<int32_t> (*this, random);
TheTest::template run<int64_t> (*this, random);
}
void runTest() void runTest()
{ {
runTestForAllTypes<InitializationTest> ("InitializationTest"); runTestForAllTypes<InitializationTest> ("InitializationTest");
@@ -833,6 +871,8 @@ public:
runTestForAllTypes<CheckMultiplyAdd> ("CheckMultiplyAdd"); runTestForAllTypes<CheckMultiplyAdd> ("CheckMultiplyAdd");
runTestForAllTypes<CheckSum> ("CheckSum"); runTestForAllTypes<CheckSum> ("CheckSum");
runTestSigned<CheckAbs> ("CheckAbs");
} }
}; };


Loading…
Cancel
Save