SIMD cleanups

This commit is contained in:
paul 2019-08-22 10:43:33 +02:00
parent 069309d426
commit 3a4c084918
5 changed files with 59 additions and 84 deletions

View file

@ -142,10 +142,6 @@ target_link_libraries(sfizz_tests Catch2::Catch2 absl::strings absl::flat_hash_m
target_include_directories(sfizz_tests SYSTEM PRIVATE sources) target_include_directories(sfizz_tests SYSTEM PRIVATE sources)
file(COPY "tests" DESTINATION ${CMAKE_BINARY_DIR}) file(COPY "tests" DESTINATION ${CMAKE_BINARY_DIR})
###############################
add_executable(bench_span benchmarks/Spans.cpp)
target_link_libraries(bench_span benchmark gsl::gsl-lite absl::span)
############################### ###############################
add_executable(bench_opf_high_vs_low benchmarks/OPF_high_vs_low.cpp) add_executable(bench_opf_high_vs_low benchmarks/OPF_high_vs_low.cpp)
target_link_libraries(bench_opf_high_vs_low benchmark absl::span) target_link_libraries(bench_opf_high_vs_low benchmark absl::span)

View file

@ -14,19 +14,10 @@ void writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span
} }
// template<class Type, bool SIMD=false> // template<class Type, bool SIMD=false>
// void loopingSFZIndex(absl::Span<const Type> inputLeft, absl::Span<const Type> inputRight, absl::Span<Type> output); // void linearRamp(absl::Span<Type> output, Type start, Type step);
// template<class Type, bool SIMD=false> // template<class Type, bool SIMD=false>
// void linearRamp(absl::Span<Type> output, Type start, Type end); // void exponentialRamp(absl::Span<Type> output, Type start, Type step);
// template<class Type, bool SIMD=false>
// void exponentialRamp(absl::Span<Type> output, Type start, Type end);
// template<class Type, bool SIMD=false>
// void applyGain(Type gain, absl::Span<Type> output);
// template<class Type, bool SIMD=false>
// void applyGain(absl::Span<const Type> output, absl::Span<Type> output);
template<> template<>
void fill<float, true>(absl::Span<float> output, float value) noexcept void fill<float, true>(absl::Span<float> output, float value) noexcept

View file

@ -1,8 +1,16 @@
#include "Globals.h" #include "Globals.h"
#include <absl/types/span.h> #include <absl/types/span.h>
#include <absl/algorithm/container.h>
#include "Helpers.h" #include "Helpers.h"
#include <cmath> #include <cmath>
template<class T>
inline void snippetRead(const T*& input, T*& outputLeft, T*& outputRight)
{
*outputLeft++ = *input++;
*outputRight++ = *input++;
}
template<class T, bool SIMD=SIMDConfig::readInterleaved> template<class T, bool SIMD=SIMDConfig::readInterleaved>
void readInterleaved(absl::Span<const T> input, absl::Span<T> outputLeft, absl::Span<T> outputRight) noexcept void readInterleaved(absl::Span<const T> input, absl::Span<T> outputLeft, absl::Span<T> outputRight) noexcept
{ {
@ -14,10 +22,14 @@ void readInterleaved(absl::Span<const T> input, absl::Span<T> outputLeft, absl::
auto* lOut = outputLeft.begin(); auto* lOut = outputLeft.begin();
auto* rOut = outputRight.begin(); auto* rOut = outputRight.begin();
while (in < (input.end() - 1) && lOut < outputLeft.end() && rOut < outputRight.end()) while (in < (input.end() - 1) && lOut < outputLeft.end() && rOut < outputRight.end())
{ snippetRead<T>(in, lOut, rOut);
*lOut++ = *in++; }
*rOut++ = *in++;
} template<class T>
inline void snippetWrite(T*& output, const T*& inputLeft, const T*& inputRight)
{
*output++ = *inputLeft++;
*output++ = *inputRight++;
} }
template<class T, bool SIMD=SIMDConfig::writeInterleaved> template<class T, bool SIMD=SIMDConfig::writeInterleaved>
@ -30,10 +42,7 @@ void writeInterleaved(absl::Span<const T> inputLeft, absl::Span<const T> inputRi
auto* rIn = inputRight.begin(); auto* rIn = inputRight.begin();
auto* out = output.begin(); auto* out = output.begin();
while (lIn < inputLeft.end() && rIn < inputRight.end() && out < (output.end() - 1)) while (lIn < inputLeft.end() && rIn < inputRight.end() && out < (output.end() - 1))
{ snippetWrite<T>(out, lIn, rIn);
*out++ = *lIn++;
*out++ = *rIn++;
}
} }
// Specializations // Specializations
@ -45,7 +54,7 @@ void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<floa
template<class T, bool SIMD=SIMDConfig::fill> template<class T, bool SIMD=SIMDConfig::fill>
void fill(absl::Span<T> output, T value) noexcept void fill(absl::Span<T> output, T value) noexcept
{ {
std::fill(output.begin(), output.end(), value); absl::c_fill(output, value);
} }
template<> template<>
@ -99,6 +108,21 @@ void cos(absl::Span<const Type> input, absl::Span<Type> output) noexcept
template<> template<>
void cos<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept; void cos<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept;
template<class T>
inline void snippetLoopingIndex(const T*& jump, T*& leftCoeff, T*& rightCoeff, int*& index, T& floatIndex, T loopEnd, T loopStart)
{
floatIndex += *jump;
if (floatIndex >= loopEnd)
floatIndex -= loopEnd - loopStart;
*index = static_cast<int>(floatIndex);
*rightCoeff = floatIndex - *index;
*leftCoeff = 1.0f - *rightCoeff;
index++;
leftCoeff++;
rightCoeff++;
jump++;
}
template<class T, bool SIMD=SIMDConfig::useSIMD> template<class T, bool SIMD=SIMDConfig::useSIMD>
void loopingSFZIndex(absl::Span<const T> jumps, absl::Span<T> leftCoeffs, absl::Span<T> rightCoeffs, absl::Span<int> indices, T floatIndex, T loopEnd, T loopStart) noexcept void loopingSFZIndex(absl::Span<const T> jumps, absl::Span<T> leftCoeffs, absl::Span<T> rightCoeffs, absl::Span<int> indices, T floatIndex, T loopEnd, T loopStart) noexcept
{ {
@ -114,18 +138,7 @@ void loopingSFZIndex(absl::Span<const T> jumps, absl::Span<T> leftCoeffs, absl::
auto* sentinel = jumps.begin() + size; auto* sentinel = jumps.begin() + size;
while (jump < sentinel) while (jump < sentinel)
{ snippetLoopingIndex<T>(jump, leftCoeff, rightCoeff, index, floatIndex, loopEnd, loopStart);
floatIndex += *jump;
if (floatIndex >= loopEnd)
floatIndex -= loopEnd - loopStart;
*index = static_cast<int>(floatIndex);
*rightCoeff = floatIndex - *index;
*leftCoeff = 1.0f - *rightCoeff;
index++;
leftCoeff++;
rightCoeff++;
jump++;
}
} }
template<> template<>
@ -137,6 +150,12 @@ void linearRamp(absl::Span<T> output, T start, T end);
template<class T, bool SIMD=SIMDConfig::useSIMD> template<class T, bool SIMD=SIMDConfig::useSIMD>
void exponentialRamp(absl::Span<T> output, T start, T end); void exponentialRamp(absl::Span<T> output, T start, T end);
template<class T>
inline void snippetGain(T gain, const T*& input, T*& output)
{
*output++ = gain * (*input++);
}
template<class T, bool SIMD=SIMDConfig::gain> template<class T, bool SIMD=SIMDConfig::gain>
void applyGain(T gain, absl::Span<const T> input, absl::Span<T> output) noexcept void applyGain(T gain, absl::Span<const T> input, absl::Span<T> output) noexcept
{ {
@ -145,9 +164,13 @@ void applyGain(T gain, absl::Span<const T> input, absl::Span<T> output) noexcept
auto* out = output.begin(); auto* out = output.begin();
auto* sentinel = out + std::min(output.size(), input.size()); auto* sentinel = out + std::min(output.size(), input.size());
while (out < sentinel) while (out < sentinel)
{ snippetGain<T>(gain, in, out);
*out++ = gain * (*in++); }
}
template<class T>
inline void snippetGainSpan(const T*& gain, const T*& input, T*& output)
{
*output++ = (*gain++) * (*input++);
} }
template<class T, bool SIMD=SIMDConfig::gain> template<class T, bool SIMD=SIMDConfig::gain>
@ -160,9 +183,7 @@ void applyGain(absl::Span<const T> gain, absl::Span<const T> input, absl::Span<T
auto* out = output.begin(); auto* out = output.begin();
auto* sentinel = out + std::min(gain.size(), std::min(output.size(), input.size())); auto* sentinel = out + std::min(gain.size(), std::min(output.size(), input.size()));
while (out < sentinel) while (out < sentinel)
{ snippetGainSpan<T>(g, in, out);
*out++ = (*g++) * (*in++);
}
} }
template<class T, bool SIMD=SIMDConfig::gain> template<class T, bool SIMD=SIMDConfig::gain>

View file

@ -59,10 +59,7 @@ void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<floa
const auto* lastAligned = prevAligned(input.begin() + size - TypeAlignment); const auto* lastAligned = prevAligned(input.begin() + size - TypeAlignment);
while (unaligned(in, lOut, rOut) && in < lastAligned) while (unaligned(in, lOut, rOut) && in < lastAligned)
{ snippetRead<float>(in, lOut, rOut);
*lOut++ = *in++;
*rOut++ = *in++;
}
while (in < lastAligned ) while (in < lastAligned )
{ {
@ -83,10 +80,7 @@ void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<floa
} }
while (in < input.end() - 1) while (in < input.end() - 1)
{ snippetRead<float>(in, lOut, rOut);
*lOut++ = *in++;
*rOut++ = *in++;
}
} }
template<> template<>
@ -104,10 +98,7 @@ void writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span
const auto* lastAligned = prevAligned(output.begin() + size - TypeAlignment); const auto* lastAligned = prevAligned(output.begin() + size - TypeAlignment);
while (unaligned(out, rIn, lIn) && out < lastAligned) while (unaligned(out, rIn, lIn) && out < lastAligned)
{ snippetWrite<float>(out, lIn, rIn);
*out++ = *lIn++;
*out++ = *rIn++;
}
while (out < lastAligned) while (out < lastAligned)
{ {
@ -127,10 +118,7 @@ void writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span
} }
while (out < output.end() - 1) while (out < output.end() - 1)
{ snippetWrite<float>(out, lIn, rIn);
*out++ = *lIn++;
*out++ = *rIn++;
}
} }
@ -247,7 +235,7 @@ void applyGain<float, true>(absl::Span<const float> gain, absl::Span<const float
const auto* lastAligned = prevAligned(output.begin() + size); const auto* lastAligned = prevAligned(output.begin() + size);
while (unaligned(out, in, g) && out < lastAligned) while (unaligned(out, in, g) && out < lastAligned)
*out++ = (*g++) * (*in++); snippetGainSpan<float>(g, in, out);
while (out < lastAligned) while (out < lastAligned)
{ {
@ -258,7 +246,7 @@ void applyGain<float, true>(absl::Span<const float> gain, absl::Span<const float
} }
while (out < output.end()) while (out < output.end())
*out++ = (*g++) * (*in++); snippetGainSpan<float>(g, in, out);
} }
template<> template<>
@ -277,18 +265,7 @@ void loopingSFZIndex<float, true>(absl::Span<const float> jumps, absl::Span<floa
const auto* alignedEnd = prevAligned(sentinel); const auto* alignedEnd = prevAligned(sentinel);
while (unaligned(reinterpret_cast<float*>(index), leftCoeff, rightCoeff, jump) && jump < alignedEnd) while (unaligned(reinterpret_cast<float*>(index), leftCoeff, rightCoeff, jump) && jump < alignedEnd)
{ snippetLoopingIndex<float>(jump, leftCoeff, rightCoeff, index, floatIndex, loopEnd, loopStart);
floatIndex += *jump;
if (floatIndex >= loopEnd)
floatIndex -= loopEnd - loopStart;
*index = static_cast<int>(floatIndex);
*rightCoeff = floatIndex - *index;
*leftCoeff = 1.0f - *rightCoeff;
index++;
leftCoeff++;
rightCoeff++;
jump++;
}
auto mmFloatIndex = _mm_set_ps1(floatIndex); auto mmFloatIndex = _mm_set_ps1(floatIndex);
const auto mmJumpBack = _mm_set1_ps(loopEnd - loopStart); const auto mmJumpBack = _mm_set1_ps(loopEnd - loopStart);
@ -325,16 +302,5 @@ void loopingSFZIndex<float, true>(absl::Span<const float> jumps, absl::Span<floa
floatIndex = _mm_cvtss_f32(mmFloatIndex); floatIndex = _mm_cvtss_f32(mmFloatIndex);
while (jump < sentinel) while (jump < sentinel)
{ snippetLoopingIndex<float>(jump, leftCoeff, rightCoeff, index, floatIndex, loopEnd, loopStart);
floatIndex += *jump;
if (floatIndex >= loopEnd)
floatIndex -= loopEnd - loopStart;
*index = static_cast<int>(floatIndex);
*rightCoeff = floatIndex - *index;
*leftCoeff = 1.0f - *rightCoeff;
index++;
leftCoeff++;
rightCoeff++;
jump++;
}
} }

View file

@ -2,6 +2,7 @@
#include "../sources/SIMDHelpers.h" #include "../sources/SIMDHelpers.h"
#include <array> #include <array>
#include <algorithm> #include <algorithm>
#include <iostream>
#include <absl/types/span.h> #include <absl/types/span.h>
#include <absl/algorithm/container.h> #include <absl/algorithm/container.h>
using namespace Catch::literals; using namespace Catch::literals;