SIMD cleanups
This commit is contained in:
parent
069309d426
commit
3a4c084918
5 changed files with 59 additions and 84 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue