Use a dispatching object rather than branchesUpdate the benchmarksRemove the SIMDInitializerInfer type for simd helpers

This commit is contained in:
Paul Ferrand 2020-06-03 21:57:04 +02:00 committed by Jean Pierre Cimalando
parent c0fac2cfbb
commit da9e503657
31 changed files with 498 additions and 541 deletions

View file

@ -36,39 +36,39 @@ public:
BENCHMARK_DEFINE_F(AddArray, Value_Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::add, false);
sfz::add<float>(1.1f, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add1, false);
sfz::add1<float>(1.1f, absl::MakeSpan(output));
}
}
BENCHMARK_DEFINE_F(AddArray, Value_SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::add, true);
sfz::add<float>(1.1f, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add1, true);
sfz::add1<float>(1.1f, absl::MakeSpan(output));
}
}
BENCHMARK_DEFINE_F(AddArray, Value_Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::add, false);
sfz::add<float>(1.1f, absl::MakeSpan(output).subspan(1));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add1, false);
sfz::add1<float>(1.1f, absl::MakeSpan(output).subspan(1));
}
}
BENCHMARK_DEFINE_F(AddArray, Value_SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::add, true);
sfz::add<float>(1.1f, absl::MakeSpan(output).subspan(1));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add1, true);
sfz::add1<float>(1.1f, absl::MakeSpan(output).subspan(1));
}
}
BENCHMARK_DEFINE_F(AddArray, Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::add, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add, false);
sfz::add<float>(input, absl::MakeSpan(output));
}
}
@ -76,7 +76,7 @@ BENCHMARK_DEFINE_F(AddArray, Scalar)(benchmark::State& state) {
BENCHMARK_DEFINE_F(AddArray, SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::add, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add, true);
sfz::add<float>(input, absl::MakeSpan(output));
}
}
@ -84,7 +84,7 @@ BENCHMARK_DEFINE_F(AddArray, SIMD)(benchmark::State& state) {
BENCHMARK_DEFINE_F(AddArray, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::add, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add, false);
sfz::add<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -92,7 +92,7 @@ BENCHMARK_DEFINE_F(AddArray, Scalar_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(AddArray, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::add, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add, true);
sfz::add<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -43,7 +43,7 @@ BENCHMARK_DEFINE_F(CopyArray, StdCopy)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CopyArray, Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::copy, false);
sfz::copy<float>(input, absl::MakeSpan(output));
}
}
@ -51,7 +51,7 @@ BENCHMARK_DEFINE_F(CopyArray, Scalar)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CopyArray, SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::copy, true);
sfz::copy<float>(input, absl::MakeSpan(output));
}
}
@ -66,7 +66,7 @@ BENCHMARK_DEFINE_F(CopyArray, StdCopy_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CopyArray, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::copy, false);
sfz::copy<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -74,7 +74,7 @@ BENCHMARK_DEFINE_F(CopyArray, Scalar_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CopyArray, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::copy, true);
sfz::copy<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -35,7 +35,7 @@ public:
BENCHMARK_DEFINE_F(CumArray, Sum_Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::cumsum, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::cumsum, false);
sfz::cumsum<float>(input, absl::MakeSpan(output));
}
}
@ -43,7 +43,7 @@ BENCHMARK_DEFINE_F(CumArray, Sum_Scalar)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CumArray, Sum_SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::cumsum, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::cumsum, true);
sfz::cumsum<float>(input, absl::MakeSpan(output));
}
}
@ -51,7 +51,7 @@ BENCHMARK_DEFINE_F(CumArray, Sum_SIMD)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CumArray, Sum_Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::cumsum, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::cumsum, false);
sfz::cumsum<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -59,7 +59,7 @@ BENCHMARK_DEFINE_F(CumArray, Sum_Scalar_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(CumArray, Sum_SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::cumsum, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::cumsum, true);
sfz::cumsum<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -37,7 +37,7 @@ public:
BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::diff, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::diff, false);
sfz::diff<float>(input, absl::MakeSpan(output));
}
}
@ -45,7 +45,7 @@ BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar)(benchmark::State& state) {
BENCHMARK_DEFINE_F(DiffArray, Diff_SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::diff, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::diff, true);
sfz::diff<float>(input, absl::MakeSpan(output));
}
}
@ -53,7 +53,7 @@ BENCHMARK_DEFINE_F(DiffArray, Diff_SIMD)(benchmark::State& state) {
BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::diff, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::diff, false);
sfz::diff<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -61,7 +61,7 @@ BENCHMARK_DEFINE_F(DiffArray, Diff_Scalar_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(DiffArray, Diff_SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::diff, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::diff, true);
sfz::diff<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -46,7 +46,7 @@ BENCHMARK_DEFINE_F(Divide, Straight)(benchmark::State& state) {
BENCHMARK_DEFINE_F(Divide, Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::divide, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::divide, false);
sfz::divide<float>(input, divisor, absl::MakeSpan(output));
}
}
@ -54,7 +54,7 @@ BENCHMARK_DEFINE_F(Divide, Scalar)(benchmark::State& state) {
BENCHMARK_DEFINE_F(Divide, SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::divide, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::divide, true);
sfz::divide<float>(input, divisor, absl::MakeSpan(output));
}
}
@ -62,7 +62,7 @@ BENCHMARK_DEFINE_F(Divide, SIMD)(benchmark::State& state) {
BENCHMARK_DEFINE_F(Divide, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::divide, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::divide, false);
sfz::divide<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(divisor).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -70,7 +70,7 @@ BENCHMARK_DEFINE_F(Divide, Scalar_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(Divide, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::divide, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::divide, true);
sfz::divide<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(divisor).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -66,16 +66,16 @@ BENCHMARK_DEFINE_F(GainSingle, Straight)(benchmark::State& state) {
BENCHMARK_DEFINE_F(GainSingle, Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain1, false);
sfz::applyGain1<float>(gain, input, absl::MakeSpan(output));
}
}
BENCHMARK_DEFINE_F(GainSingle, SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain1, true);
sfz::applyGain1<float>(gain, input, absl::MakeSpan(output));
}
}
@ -90,7 +90,7 @@ BENCHMARK_DEFINE_F(GainArray, Straight)(benchmark::State& state) {
BENCHMARK_DEFINE_F(GainArray, Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
}
}
@ -98,7 +98,7 @@ BENCHMARK_DEFINE_F(GainArray, Scalar)(benchmark::State& state) {
BENCHMARK_DEFINE_F(GainArray, SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain, true);
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
}
}
@ -106,7 +106,7 @@ BENCHMARK_DEFINE_F(GainArray, SIMD)(benchmark::State& state) {
BENCHMARK_DEFINE_F(GainArray, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -114,7 +114,7 @@ BENCHMARK_DEFINE_F(GainArray, Scalar_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(GainArray, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain, true);
sfz::applyGain<float>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -34,7 +34,7 @@ BENCHMARK_DEFINE_F(MeanArray, Scalar)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::mean, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::mean, false);
auto result = sfz::mean<float>(input);
benchmark::DoNotOptimize(result);
}
@ -44,7 +44,7 @@ BENCHMARK_DEFINE_F(MeanArray, SIMD)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::mean, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::mean, true);
auto result = sfz::mean<float>(input);
benchmark::DoNotOptimize(result);
}
@ -54,7 +54,7 @@ BENCHMARK_DEFINE_F(MeanArray, Scalar_Unaligned)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::mean, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::mean, false);
auto result = sfz::mean<float>(absl::MakeSpan(input).subspan(1));
benchmark::DoNotOptimize(result);
}
@ -64,7 +64,7 @@ BENCHMARK_DEFINE_F(MeanArray, SIMD_Unaligned)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::mean, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::mean, true);
auto result = sfz::mean<float>(absl::MakeSpan(input).subspan(1));
benchmark::DoNotOptimize(result);
}

View file

@ -34,7 +34,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, Scalar)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::meanSquared, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, false);
auto result = sfz::meanSquared<float>(input);
benchmark::DoNotOptimize(result);
}
@ -44,7 +44,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, SIMD)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::meanSquared, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, true);
auto result = sfz::meanSquared<float>(input);
benchmark::DoNotOptimize(result);
}
@ -54,7 +54,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, Scalar_Unaligned)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::meanSquared, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, false);
auto result = sfz::meanSquared<float>(absl::MakeSpan(input).subspan(1));
benchmark::DoNotOptimize(result);
}
@ -64,7 +64,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, SIMD_Unaligned)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::meanSquared, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, true);
auto result = sfz::meanSquared<float>(absl::MakeSpan(input).subspan(1));
benchmark::DoNotOptimize(result);
}

View file

@ -46,7 +46,7 @@ BENCHMARK_DEFINE_F(MultiplyAdd, Straight)(benchmark::State& state) {
BENCHMARK_DEFINE_F(MultiplyAdd, Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd, false);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(output));
}
}
@ -54,7 +54,7 @@ BENCHMARK_DEFINE_F(MultiplyAdd, Scalar)(benchmark::State& state) {
BENCHMARK_DEFINE_F(MultiplyAdd, SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd, true);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(output));
}
}
@ -62,7 +62,7 @@ BENCHMARK_DEFINE_F(MultiplyAdd, SIMD)(benchmark::State& state) {
BENCHMARK_DEFINE_F(MultiplyAdd, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd, false);
sfz::multiplyAdd<float>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -70,7 +70,7 @@ BENCHMARK_DEFINE_F(MultiplyAdd, Scalar_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(MultiplyAdd, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd, true);
sfz::multiplyAdd<float>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -48,8 +48,8 @@ BENCHMARK_DEFINE_F(MultiplyAddFixedGain, Scalar)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, false);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd1, false);
sfz::multiplyAdd1<float>(gain, input, absl::MakeSpan(output));
}
}
@ -57,8 +57,8 @@ BENCHMARK_DEFINE_F(MultiplyAddFixedGain, SIMD)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, true);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd1, true);
sfz::multiplyAdd1<float>(gain, input, absl::MakeSpan(output));
}
}
@ -66,8 +66,8 @@ BENCHMARK_DEFINE_F(MultiplyAddFixedGain, Scalar_Unaligned)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, false);
sfz::multiplyAdd<float>(gain, absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd1, false);
sfz::multiplyAdd1<float>(gain, absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -75,8 +75,8 @@ BENCHMARK_DEFINE_F(MultiplyAddFixedGain, SIMD_Unaligned)
(benchmark::State& state)
{
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, true);
sfz::multiplyAdd<float>(gain, absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd1, true);
sfz::multiplyAdd1<float>(gain, absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -30,7 +30,7 @@ static void LinearScalar(benchmark::State& state) {
for (auto _ : state)
{
auto value = dist(gen);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, false);
sfz::linearRamp<float>(absl::MakeSpan(output), 0.0f, value);
}
}
@ -43,7 +43,7 @@ static void LinearSIMD(benchmark::State& state) {
for (auto _ : state)
{
auto value = dist(gen);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
sfz::linearRamp<float>(absl::MakeSpan(output), 0.0f, value);
}
}
@ -55,7 +55,7 @@ static void LinearScalarUnaligned(benchmark::State& state) {
for (auto _ : state)
{
auto value = dist(gen);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, false);
sfz::linearRamp<float>(absl::MakeSpan(output).subspan(1), 0.0f, value);
}
}
@ -68,7 +68,7 @@ static void LinearSIMDUnaligned(benchmark::State& state) {
for (auto _ : state)
{
auto value = dist(gen);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
sfz::linearRamp<float>(absl::MakeSpan(output).subspan(1), 0.0f, value);
}
}
@ -81,7 +81,7 @@ static void MulScalar(benchmark::State& state) {
for (auto _ : state)
{
auto value = dist(gen);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, false);
sfz::multiplicativeRamp<float>(absl::MakeSpan(output), 1.0f, value);
}
}
@ -94,7 +94,7 @@ static void MulSIMD(benchmark::State& state) {
for (auto _ : state)
{
auto value = dist(gen);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, true);
sfz::multiplicativeRamp<float>(absl::MakeSpan(output), 1.0f, value);
}
}
@ -106,7 +106,7 @@ static void MulScalarUnaligned(benchmark::State& state) {
for (auto _ : state)
{
auto value = dist(gen);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, false);
sfz::multiplicativeRamp<float>(absl::MakeSpan(output).subspan(1), 1.0f, value);
}
}
@ -119,7 +119,7 @@ static void MulSIMDUnaligned(benchmark::State& state) {
for (auto _ : state)
{
auto value = dist(gen);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, true);
sfz::multiplicativeRamp<float>(absl::MakeSpan(output).subspan(1), 1.0f, value);
}
}

View file

@ -18,7 +18,7 @@ static void Scalar(benchmark::State& state) {
std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, false);
sfz::readInterleaved(input, absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight));
}
}
@ -30,7 +30,7 @@ static void SSE(benchmark::State& state) {
std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, true);
sfz::readInterleaved(input, absl::MakeSpan(outputLeft), absl::MakeSpan(outputRight));
}
}
@ -41,7 +41,7 @@ static void Scalar_Unaligned(benchmark::State& state) {
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, false);
sfz::readInterleaved(
absl::MakeSpan(input).subspan(2),
absl::MakeSpan(outputLeft),
@ -56,7 +56,7 @@ static void SSE_Unaligned(benchmark::State& state) {
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, true);
sfz::readInterleaved(
absl::MakeSpan(input).subspan(2),
absl::MakeSpan(outputLeft),
@ -71,7 +71,7 @@ static void Scalar_Unaligned_2(benchmark::State& state) {
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, false);
sfz::readInterleaved(
absl::MakeSpan(input).subspan(2),
absl::MakeSpan(outputLeft).subspan(1),
@ -86,7 +86,7 @@ static void SSE_Unaligned_2(benchmark::State& state) {
sfz::Buffer<float> outputRight (state.range(0));
std::iota(input.begin(), input.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, true);
sfz::readInterleaved(
absl::MakeSpan(input).subspan(2),
absl::MakeSpan(outputLeft).subspan(1),

View file

@ -36,7 +36,7 @@ public:
BENCHMARK_DEFINE_F(SubArray, Scalar)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract, false);
sfz::subtract<float>(input, absl::MakeSpan(output));
}
}
@ -44,7 +44,7 @@ BENCHMARK_DEFINE_F(SubArray, Scalar)(benchmark::State& state) {
BENCHMARK_DEFINE_F(SubArray, SIMD)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract, true);
sfz::subtract<float>(input, absl::MakeSpan(output));
}
}
@ -52,7 +52,7 @@ BENCHMARK_DEFINE_F(SubArray, SIMD)(benchmark::State& state) {
BENCHMARK_DEFINE_F(SubArray, Scalar_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract, false);
sfz::subtract<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}
@ -60,7 +60,7 @@ BENCHMARK_DEFINE_F(SubArray, Scalar_Unaligned)(benchmark::State& state) {
BENCHMARK_DEFINE_F(SubArray, SIMD_Unaligned)(benchmark::State& state) {
for (auto _ : state)
{
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract, true);
sfz::subtract<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
}
}

View file

@ -19,7 +19,7 @@ static void Interleaved_Write(benchmark::State& state) {
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, false);
sfz::writeInterleaved(inputLeft, inputRight, absl::MakeSpan(output));
}
}
@ -31,7 +31,7 @@ static void Interleaved_Write_SSE(benchmark::State& state) {
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, true);
sfz::writeInterleaved(inputLeft, inputRight, absl::MakeSpan(output));
}
}
@ -43,7 +43,7 @@ static void Unaligned_Interleaved_Write(benchmark::State& state) {
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, false);
sfz::writeInterleaved(
absl::MakeSpan(inputLeft).subspan(1),
absl::MakeSpan(inputRight).subspan(1),
@ -59,7 +59,7 @@ static void Unaligned_Interleaved_Write_SSE(benchmark::State& state) {
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, true);
sfz::writeInterleaved(
absl::MakeSpan(inputLeft).subspan(1),
absl::MakeSpan(inputRight).subspan(1),
@ -75,7 +75,7 @@ static void Unaligned_Interleaved_Write_2(benchmark::State& state) {
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, false);
sfz::writeInterleaved(
absl::MakeSpan(inputLeft),
absl::MakeSpan(inputRight).subspan(1),
@ -91,7 +91,7 @@ static void Unaligned_Interleaved_Write_SSE_2(benchmark::State& state) {
std::iota(inputLeft.begin(), inputLeft.end(), 1.0f);
std::iota(inputRight.begin(), inputRight.end(), 1.0f);
for (auto _ : state) {
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, true);
sfz::writeInterleaved(
absl::MakeSpan(inputLeft),
absl::MakeSpan(inputRight).subspan(1),

View file

@ -32,4 +32,5 @@ clang-tidy \
vst/SfizzVstState.cpp \
-- -Iexternal/abseil-cpp -Isrc/external -Isrc/external/pugixml/src \
-Isrc/sfizz -Isrc -Isrc/external/spline -Isrc/external/cpuid/src \
-Ivst -Ivst/external/VST_SDK/VST3_SDK -Ivst/external/VST_SDK/VST3_SDK/vstgui4 -Ivst/external/ring_buffer -DNDEBUG
-Ivst -Ivst/external/VST_SDK/VST3_SDK -Ivst/external/VST_SDK/VST3_SDK/vstgui4 -Ivst/external/ring_buffer \
-DNDEBUG -std=c++17

View file

@ -303,7 +303,7 @@ public:
{
static_assert(!std::is_const<Type>::value, "Can't allow mutating operations on const AudioSpans");
for (size_t i = 0; i < numChannels; ++i)
sfz::applyGain<Type>(gain, getSpan(i));
sfz::applyGain1<Type>(gain, getSpan(i));
}
/**

View file

@ -46,7 +46,7 @@
std::cerr << "Check failed at " << __FILE__ << ":" << __LINE__ << '\n'; \
} while (0)
#define CHECK(expression) \
#define SFIZZ_CHECK(expression) \
do { \
if (!(expression)) { \
std::cerr << "Check failed: " << #expression << '\n'; \
@ -59,7 +59,7 @@
#define ASSERTFALSE do {} while (0)
#define ASSERT(expression) do {} while (0)
#define CHECKFALSE do {} while (0)
#define CHECK(expression) do {} while (0)
#define SFIZZ_CHECK(expression) do {} while (0)
#endif

View file

@ -105,7 +105,7 @@ void EffectBus::addToInputs(const float* const addInput[], float addGain, unsign
for (unsigned c = 0; c < EffectChannels; ++c) {
absl::Span<const float> addIn { addInput[c], nframes };
sfz::multiplyAdd(addGain, addIn, _inputs.getSpan(c).first(nframes));
sfz::multiplyAdd1(addGain, addIn, _inputs.getSpan(c).first(nframes));
}
}
@ -154,8 +154,8 @@ void EffectBus::mixOutputsTo(float* const mainOutput[], float* const mixOutput[]
for (unsigned c = 0; c < EffectChannels; ++c) {
auto fxOut = _outputs.getConstSpan(c).first(nframes);
sfz::multiplyAdd(gainToMain, fxOut, absl::Span<float>(mainOutput[c], nframes));
sfz::multiplyAdd(gainToMix, fxOut, absl::Span<float>(mixOutput[c], nframes));
sfz::multiplyAdd1(gainToMain, fxOut, absl::Span<float>(mainOutput[c], nframes));
sfz::multiplyAdd1(gainToMix, fxOut, absl::Span<float>(mixOutput[c], nframes));
}
}

View file

@ -491,7 +491,7 @@ constexpr bool checkSpanSizes(const absl::Span<T>& span1, Others... others)
return _checkSpanSizes(span1.size(), others...);
}
#define CHECK_SPAN_SIZES(...) CHECK(checkSpanSizes(__VA_ARGS__))
#define CHECK_SPAN_SIZES(...) SFIZZ_CHECK(checkSpanSizes(__VA_ARGS__))
class ScopedRoundingMode {

View file

@ -18,326 +18,141 @@ namespace sfz {
template <class T>
struct SIMDDispatch {
constexpr SIMDDispatch() = default;
void resetStatus();
bool getStatus(SIMDOps op) const;
void setStatus(SIMDOps op, bool enable);
void (*writeInterleaved)(const T* inputLeft, const T* inputRight, T* output, unsigned outputSize) noexcept = &writeInterleavedScalar<float>;
void (*readInterleaved)(const T* input, T* outputLeft, T* outputRight, unsigned inputSize) noexcept = &readInterleavedScalar<float>;
void (*applyGain)(const T* gain, const T* input, T* output, unsigned size) noexcept = &applyGainScalar<float>;
void (*applyGain1)(T gain, const T* input, T* output, unsigned size) noexcept = &applyGainScalar<float>;
void (*divide)(const T* input, const T* divisor, T* output, unsigned size) noexcept = &divideScalar<float>;
void (*multiplyAdd)(const T* gain, const T* input, T* output, unsigned size) noexcept = &multiplyAddScalar<float>;
void (*multiplyAdd1)(T gain, const T* input, T* output, unsigned size) noexcept = &multiplyAddScalar<float>;
T (*linearRamp)(T* output, T start, T step, unsigned size) noexcept = &linearRampScalar<float>;
T (*multiplicativeRamp)(T* output, T start, T step, unsigned size) noexcept = &multiplicativeRampScalar<float>;
void (*add)(const T* input, T* output, unsigned size) noexcept = &addScalar<float>;
void (*add1)(T value, T* output, unsigned size) noexcept = &addScalar<float>;
void (*subtract)(const T* input, T* output, unsigned size) noexcept = &subtractScalar<float>;
void (*subtract1)(T value, T* output, unsigned size) noexcept = &subtractScalar<float>;
void (*copy)(const T* input, T* output, unsigned size) noexcept = &copyScalar<float>;
void (*cumsum)(const T* input, T* output, unsigned size) noexcept = &cumsumScalar<float>;
void (*diff)(const T* input, T* output, unsigned size) noexcept = &diffScalar<float>;
T (*mean)(const T* vector, unsigned size) noexcept = &meanScalar<float>;
T (*meanSquared)(const T* vector, unsigned size) noexcept = &meanSquaredScalar<float>;
decltype(&writeInterleavedScalar<T>) writeInterleaved = &writeInterleavedScalar<T>;
decltype(&readInterleavedScalar<T>) readInterleaved = &readInterleavedScalar<T>;
decltype(&gainScalar<T>) gain = &gainScalar<T>;
decltype(&gain1Scalar<T>) gain1 = &gain1Scalar<T>;
decltype(&divideScalar<T>) divide = &divideScalar<T>;
decltype(&multiplyAddScalar<T>) multiplyAdd = &multiplyAddScalar<T>;
decltype(&multiplyAdd1Scalar<T>) multiplyAdd1 = &multiplyAdd1Scalar<T>;
decltype(&linearRampScalar<T>) linearRamp = &linearRampScalar<T>;
decltype(&multiplicativeRampScalar<T>) multiplicativeRamp = &multiplicativeRampScalar<T>;
decltype(&addScalar<T>) add = &addScalar<T>;
decltype(&add1Scalar<T>) add1 = &add1Scalar<T>;
decltype(&subtractScalar<T>) subtract = &subtractScalar<T>;
decltype(&subtract1Scalar<T>) subtract1 = &subtract1Scalar<T>;
decltype(&copyScalar<T>) copy = &copyScalar<T>;
decltype(&cumsumScalar<T>) cumsum = &cumsumScalar<T>;
decltype(&diffScalar<T>) diff = &diffScalar<T>;
decltype(&meanScalar<T>) mean = &meanScalar<T>;
decltype(&meanSquaredScalar<T>) meanSquared = &meanSquaredScalar<T>;
private:
std::array<bool, static_cast<unsigned>(SIMDOps::_sentinel)> simdStatus;
bool initialized { false };
cpuid::cpuinfo info;
};
///
static SIMDDispatch<float> simdDispatch;
void resetSIMDOpStatus()
{
simdDispatch.resetStatus();
}
void setSIMDOpStatus(SIMDOps op, bool status)
{
simdDispatch.setStatus(op, status);
}
bool getSIMDOpStatus(SIMDOps op)
{
return simdDispatch.getStatus(op);
}
///
void readInterleaved(const float* input, float* outputLeft, float* outputRight, unsigned inputSize) noexcept
{
return simdDispatch.readInterleaved(input, outputLeft, outputRight, inputSize);
}
void writeInterleaved(const float* inputLeft, const float* inputRight, float* output, unsigned outputSize) noexcept
{
return simdDispatch.writeInterleaved(inputLeft, inputRight, output, outputSize);
}
template <>
void applyGain<float>(float gain, const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.applyGain1(gain, input, output, size);
}
template <>
void applyGain<float>(const float* gain, const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.applyGain(gain, input, output, size);
}
template <>
void divide<float>(const float* input, const float* divisor, float* output, unsigned size) noexcept
{
return simdDispatch.divide(input, divisor, output, size);
}
template <>
void multiplyAdd<float>(const float* gain, const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.multiplyAdd(gain, input, output, size);
}
template <>
void multiplyAdd<float>(float gain, const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.multiplyAdd1(gain, input, output, size);
}
template <>
float linearRamp<float>(float* output, float start, float step, unsigned size) noexcept
{
return simdDispatch.linearRamp(output, start, step, size);
}
template <>
float multiplicativeRamp<float>(float* output, float start, float step, unsigned size) noexcept
{
return simdDispatch.multiplicativeRamp(output, start, step, size);
}
template <>
void add<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.add(input, output, size);
}
template <>
void add<float>(float value, float* output, unsigned size) noexcept
{
return simdDispatch.add1(value, output, size);
}
template <>
void subtract<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.subtract(input, output, size);
}
template <>
void subtract<float>(float value, float* output, unsigned size) noexcept
{
return simdDispatch.subtract1(value, output, size);
}
template <>
void copy<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.copy(input, output, size);
}
template <>
float mean<float>(const float* vector, unsigned size) noexcept
{
return simdDispatch.mean(vector, size);
}
template <>
float meanSquared<float>(const float* vector, unsigned size) noexcept
{
return simdDispatch.meanSquared(vector, size);
}
template <>
void cumsum<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.cumsum(input, output, size);
}
template <>
void diff<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch.diff(input, output, size);
}
///
static cpuid::cpuinfo& cpuInfo()
{
static cpuid::cpuinfo info;
return info;
}
template <class T>
bool SIMDDispatch<T>::getStatus(SIMDOps op) const
bool SIMDDispatch<float>::getStatus(SIMDOps op) const
{
const unsigned index = static_cast<unsigned>(op);
ASSERT(index < simdStatus.size());
return simdStatus[index];
}
template <class T>
void SIMDDispatch<T>::setStatus(SIMDOps op, bool enable)
template <>
void SIMDDispatch<float>::setStatus(SIMDOps op, bool enable)
{
const unsigned index = static_cast<unsigned>(op);
ASSERT(index < simdStatus.size());
simdStatus[index] = enable;
const cpuid::cpuinfo& info = cpuInfo();
bool useSSE = enable && info.has_sse();
bool useAVX = enable && info.has_avx();
switch (op) {
default:
break;
case SIMDOps::writeInterleaved:
if (useSSE)
writeInterleaved = &writeInterleavedSSE;
else
writeInterleaved = &writeInterleavedScalar<float>;
break;
case SIMDOps::readInterleaved:
if (useSSE)
readInterleaved = &readInterleavedSSE;
else
readInterleaved = &readInterleavedScalar<float>;
break;
case SIMDOps::gain:
if (useAVX) {
applyGain = &applyGainAVX;
applyGain1 = &applyGainAVX;
}
else if (useSSE) {
applyGain = &applyGainSSE;
applyGain1 = &applyGainSSE;
}
else {
applyGain = &applyGainScalar<float>;
applyGain1 = &applyGainScalar<float>;
}
break;
case SIMDOps::divide:
if (useSSE)
divide = &divideSSE;
else
divide = &divideScalar<float>;
break;
case SIMDOps::multiplyAdd:
if (useSSE) {
multiplyAdd = &multiplyAddSSE;
multiplyAdd1 = &multiplyAddSSE;
}
else {
multiplyAdd = &multiplyAddScalar<float>;
multiplyAdd1 = &multiplyAddScalar<float>;
}
break;
case SIMDOps::linearRamp:
if (useSSE)
linearRamp = &linearRampSSE;
else
linearRamp = &linearRampScalar<float>;
break;
case SIMDOps::multiplicativeRamp:
if (useSSE)
multiplicativeRamp = &multiplicativeRampSSE;
else
multiplicativeRamp = &multiplicativeRampScalar<float>;
break;
case SIMDOps::add:
if (useSSE) {
add = &addSSE;
add1 = &addSSE;
}
else {
add = &addScalar<float>;
add1 = &addScalar<float>;
}
break;
case SIMDOps::subtract:
if (useSSE) {
subtract = &subtractSSE;
subtract1 = &subtractSSE;
}
else {
subtract = &subtractScalar<float>;
subtract1 = &subtractScalar<float>;
}
break;
case SIMDOps::copy:
if (useSSE)
copy = &copySSE;
else
copy = &copyScalar<float>;
break;
case SIMDOps::cumsum:
if (useSSE)
cumsum = &cumsumSSE;
else
cumsum = &cumsumScalar<float>;
break;
case SIMDOps::diff:
if (useSSE)
diff = &diffSSE;
else
diff = &diffScalar<float>;
break;
case SIMDOps::mean:
if (useSSE)
mean = &meanSSE;
else
mean = &meanScalar<float>;
break;
case SIMDOps::meanSquared:
if (useSSE)
meanSquared = &meanSquaredSSE;
else
meanSquared = &meanSquaredScalar<float>;
break;
if (!enable) {
#define SIMD_OP(opname) case SIMDOps::opname : (opname) = opname ## Scalar<float>; return;
switch (op) {
default: break;
SIMD_OP(writeInterleaved)
SIMD_OP(readInterleaved)
SIMD_OP(gain)
SIMD_OP(gain1)
SIMD_OP(divide)
SIMD_OP(linearRamp)
SIMD_OP(multiplicativeRamp)
SIMD_OP(add)
SIMD_OP(add1)
SIMD_OP(subtract)
SIMD_OP(subtract1)
SIMD_OP(multiplyAdd)
SIMD_OP(multiplyAdd1)
SIMD_OP(copy)
SIMD_OP(cumsum)
SIMD_OP(diff)
SIMD_OP(mean)
SIMD_OP(meanSquared)
}
#undef SIMD_OP
}
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
#define SIMD_OP(opname) case SIMDOps::opname : (opname) = opname ## AVX; return;
if (info.has_avx()) {
switch (op) {
default: break;
}
}
#undef SIMD_OP
#define SIMD_OP(opname) case SIMDOps::opname : (opname) = opname ## SSE; return;
if (info.has_sse()) {
switch (op) {
default: break;
SIMD_OP(writeInterleaved)
SIMD_OP(readInterleaved)
SIMD_OP(gain)
SIMD_OP(gain1)
SIMD_OP(divide)
SIMD_OP(linearRamp)
SIMD_OP(multiplicativeRamp)
SIMD_OP(add)
SIMD_OP(add1)
SIMD_OP(subtract)
SIMD_OP(subtract1)
SIMD_OP(multiplyAdd)
SIMD_OP(multiplyAdd1)
SIMD_OP(copy)
SIMD_OP(cumsum)
SIMD_OP(diff)
SIMD_OP(mean)
SIMD_OP(meanSquared)
}
}
#undef SIMD_OP
#endif // SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
#if SFIZZ_CPU_FAMILY_AARCH64 || SFIZZ_CPU_FAMILY_ARM
#define SIMD_OP(opname) case SIMDOps::opname : (opname) = opname ## NEON; return;
if (info.has_neon()) {
switch (op) {
default: break;
}
}
#undef SIMD_OP
#endif // SFIZZ_CPU_FAMILY_AARCH64 || SFIZZ_CPU_FAMILY_ARM
}
template <class T>
void SIMDDispatch<T>::resetStatus()
template <>
void SIMDDispatch<float>::resetStatus()
{
setStatus(SIMDOps::writeInterleaved, false);
setStatus(SIMDOps::readInterleaved, false);
setStatus(SIMDOps::fill, true);
setStatus(SIMDOps::gain, true);
setStatus(SIMDOps::gain1, true);
setStatus(SIMDOps::divide, false);
setStatus(SIMDOps::linearRamp, false);
setStatus(SIMDOps::multiplicativeRamp, true);
setStatus(SIMDOps::add, false);
setStatus(SIMDOps::add1, false);
setStatus(SIMDOps::subtract, false);
setStatus(SIMDOps::subtract1, false);
setStatus(SIMDOps::multiplyAdd, false);
setStatus(SIMDOps::multiplyAdd1, false);
setStatus(SIMDOps::copy, false);
setStatus(SIMDOps::cumsum, true);
setStatus(SIMDOps::diff, false);
@ -349,17 +164,142 @@ void SIMDDispatch<T>::resetStatus()
///
static volatile bool simdInitialized = false;
static std::mutex simdMutex;
SIMDInitializer::SIMDInitializer()
template<class T>
static SIMDDispatch<T>& simdDispatch()
{
std::lock_guard<std::mutex> lock { simdMutex };
static SIMDDispatch<T> dispatch;
return dispatch;
}
if (!simdInitialized) {
simdDispatch.resetStatus();
simdInitialized = true;
}
template<>
void resetSIMDOpStatus<float>()
{
simdDispatch<float>().resetStatus();
}
template<>
void setSIMDOpStatus<float>(SIMDOps op, bool status)
{
simdDispatch<float>().setStatus(op, status);
}
template<>
bool getSIMDOpStatus<float>(SIMDOps op)
{
return simdDispatch<float>().getStatus(op);
}
void initializeSIMDDispatchers()
{
simdDispatch<float>().resetStatus();
}
///
void readInterleaved(const float* input, float* outputLeft, float* outputRight, unsigned inputSize) noexcept
{
return simdDispatch<float>().readInterleaved(input, outputLeft, outputRight, inputSize);
}
void writeInterleaved(const float* inputLeft, const float* inputRight, float* output, unsigned outputSize) noexcept
{
return simdDispatch<float>().writeInterleaved(inputLeft, inputRight, output, outputSize);
}
template <>
void applyGain1<float>(float gain, const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().gain1(gain, input, output, size);
}
template <>
void applyGain<float>(const float* gain, const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().gain(gain, input, output, size);
}
template <>
void divide<float>(const float* input, const float* divisor, float* output, unsigned size) noexcept
{
return simdDispatch<float>().divide(input, divisor, output, size);
}
template <>
void multiplyAdd<float>(const float* gain, const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().multiplyAdd(gain, input, output, size);
}
template <>
void multiplyAdd1<float>(float gain, const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().multiplyAdd1(gain, input, output, size);
}
template <>
float linearRamp<float>(float* output, float start, float step, unsigned size) noexcept
{
return simdDispatch<float>().linearRamp(output, start, step, size);
}
template <>
float multiplicativeRamp<float>(float* output, float start, float step, unsigned size) noexcept
{
return simdDispatch<float>().multiplicativeRamp(output, start, step, size);
}
template <>
void add<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().add(input, output, size);
}
template <>
void add1<float>(float value, float* output, unsigned size) noexcept
{
return simdDispatch<float>().add1(value, output, size);
}
template <>
void subtract<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().subtract(input, output, size);
}
template <>
void subtract1<float>(float value, float* output, unsigned size) noexcept
{
return simdDispatch<float>().subtract1(value, output, size);
}
template <>
void copy<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().copy(input, output, size);
}
template <>
float mean<float>(const float* vector, unsigned size) noexcept
{
return simdDispatch<float>().mean(vector, size);
}
template <>
float meanSquared<float>(const float* vector, unsigned size) noexcept
{
return simdDispatch<float>().meanSquared(vector, size);
}
template <>
void cumsum<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().cumsum(input, output, size);
}
template <>
void diff<float>(const float* input, float* output, unsigned size) noexcept
{
return simdDispatch<float>().diff(input, output, size);
}
}

View file

@ -42,12 +42,16 @@ enum class SIMDOps {
readInterleaved,
fill,
gain,
gain1,
divide,
linearRamp,
multiplicativeRamp,
add,
add1,
subtract,
subtract1,
multiplyAdd,
multiplyAdd1,
copy,
cumsum,
diff,
@ -58,15 +62,28 @@ enum class SIMDOps {
_sentinel //
};
// Call this at least once before using SIMD operations
void initializeSIMDDispatchers();
// Enable or disable SIMD accelerators at runtime
template<class T>
void resetSIMDOpStatus();
template<class T>
void setSIMDOpStatus(SIMDOps op, bool status);
template<class T>
bool getSIMDOpStatus(SIMDOps op);
// Initializer object which ensures to prepare SIMD dispatch
struct SIMDInitializer {
SIMDInitializer();
};
// Float specializations
template<>
void resetSIMDOpStatus<float>();
template<>
void setSIMDOpStatus<float>(SIMDOps op, bool status);
template<>
bool getSIMDOpStatus<float>(SIMDOps op);
/**
* @brief Read interleaved stereo data from a buffer and separate it in a left/right pair of buffers.
@ -81,8 +98,8 @@ void readInterleaved(const float* input, float* outputLeft, float* outputRight,
inline void readInterleaved(absl::Span<const float> input, absl::Span<float> outputLeft, absl::Span<float> outputRight) noexcept
{
// Something is fishy with the sizes
CHECK(outputLeft.size() == input.size() / 2);
CHECK(outputRight.size() == input.size() / 2);
SFIZZ_CHECK(outputLeft.size() == input.size() / 2);
SFIZZ_CHECK(outputRight.size() == input.size() / 2);
const auto size = min(input.size(), 2 * outputLeft.size(), 2 * outputRight.size());
readInterleaved(input.data(), outputLeft.data(), outputRight.data(), size);
}
@ -100,8 +117,8 @@ void writeInterleaved(const float* inputLeft, const float* inputRight, float* ou
inline void writeInterleaved(absl::Span<const float> inputLeft, absl::Span<const float> inputRight, absl::Span<float> output) noexcept
{
// Something is fishy with the sizes
CHECK(inputLeft.size() == output.size() / 2);
CHECK(inputRight.size() == output.size() / 2);
SFIZZ_CHECK(inputLeft.size() == output.size() / 2);
SFIZZ_CHECK(inputRight.size() == output.size() / 2);
const auto size = min(output.size(), 2 * inputLeft.size(), 2 * inputRight.size());
writeInterleaved(inputLeft.data(), inputRight.data(), output.data(), size);
}
@ -134,19 +151,19 @@ void fill(absl::Span<T> output, T value) noexcept
* @param size
*/
template<class T>
void applyGain(T gain, const T* input, T* output, unsigned size) noexcept
void applyGain1(T gain, const T* input, T* output, unsigned size) noexcept
{
applyGainScalar(gain, input, output, size);
gain1Scalar(gain, input, output, size);
}
template<>
void applyGain<float>(float gain, const float* input, float* output, unsigned size) noexcept;
void applyGain1<float>(float gain, const float* input, float* output, unsigned size) noexcept;
template<class T>
inline void applyGain(T gain, absl::Span<const T> input, absl::Span<T> output) noexcept
inline void applyGain1(T gain, absl::Span<const T> input, absl::Span<T> output) noexcept
{
CHECK_SPAN_SIZES(input, output);
applyGain<T>(gain, input.data(), output.data(), minSpanSize(input, output));
applyGain1<T>(gain, input.data(), output.data(), minSpanSize(input, output));
}
/**
@ -157,15 +174,15 @@ inline void applyGain(T gain, absl::Span<const T> input, absl::Span<T> output) n
* @param size
*/
template<class T>
inline void applyGain(float gain, float* array, unsigned size) noexcept
inline void applyGain1(float gain, float* array, unsigned size) noexcept
{
applyGain<T>(gain, array, array, size);
applyGain1<T>(gain, array, array, size);
}
template<class T>
inline void applyGain(float gain, absl::Span<float> array) noexcept
inline void applyGain1(float gain, absl::Span<float> array) noexcept
{
applyGain<T>(gain, array.data(), array.data(), array.size());
applyGain1<T>(gain, array.data(), array.data(), array.size());
}
/**
@ -179,7 +196,7 @@ inline void applyGain(float gain, absl::Span<float> array) noexcept
template<class T>
void applyGain(const T* gain, const T* input, T* output, unsigned size) noexcept
{
applyGainScalar(gain, input, output, size);
gainScalar(gain, input, output, size);
}
template<>
@ -288,19 +305,19 @@ void multiplyAdd(absl::Span<const T> gain, absl::Span<const T> input, absl::Span
* @param size
*/
template <class T>
void multiplyAdd(T gain, const T* input, T* output, unsigned size) noexcept
void multiplyAdd1(T gain, const T* input, T* output, unsigned size) noexcept
{
multiplyAddScalar(gain, input, output, size);
multiplyAdd1Scalar(gain, input, output, size);
}
template <>
void multiplyAdd<float>(float gain, const float* input, float* output, unsigned size) noexcept;
void multiplyAdd1<float>(float gain, const float* input, float* output, unsigned size) noexcept;
template <class T>
void multiplyAdd(T gain, absl::Span<const T> input, absl::Span<T> output) noexcept
void multiplyAdd1(T gain, absl::Span<const T> input, absl::Span<T> output) noexcept
{
CHECK_SPAN_SIZES(input, output);
multiplyAdd<T>(gain, input.data(), output.data(), minSpanSize(input, output));
multiplyAdd1<T>(gain, input.data(), output.data(), minSpanSize(input, output));
}
/**
@ -386,18 +403,18 @@ void add(absl::Span<const T> input, absl::Span<T> output) noexcept
* @param size
*/
template <class T>
void add(T value, T* output, unsigned size) noexcept
void add1(T value, T* output, unsigned size) noexcept
{
addScalar(value, output, size);
add1Scalar(value, output, size);
}
template <>
void add<float>(float value, float* output, unsigned size) noexcept;
void add1<float>(float value, float* output, unsigned size) noexcept;
template <class T>
void add(T value, absl::Span<T> output) noexcept
void add1(T value, absl::Span<T> output) noexcept
{
add<T>(value, output.data(), output.size());
add1<T>(value, output.data(), output.size());
}
/**
@ -433,18 +450,18 @@ void subtract(absl::Span<const T> input, absl::Span<T> output) noexcept
* @param size
*/
template <class T>
void subtract(T value, T* output, unsigned size) noexcept
void subtract1(T value, T* output, unsigned size) noexcept
{
subtractScalar(value, output, size);
subtract1Scalar(value, output, size);
}
template <>
void subtract<float>(float value, float* output, unsigned size) noexcept;
void subtract1<float>(float value, float* output, unsigned size) noexcept;
template <class T>
void subtract(T value, absl::Span<T> output) noexcept
void subtract1(T value, absl::Span<T> output) noexcept
{
subtract<T>(value, output.data(), output.size());
subtract1<T>(value, output.data(), output.size());
}
/**
@ -568,8 +585,8 @@ namespace _internals {
template <class T>
void sfzInterpolationCast(absl::Span<const T> floatJumps, absl::Span<int> jumps, absl::Span<T> coeffs) noexcept
{
CHECK(jumps.size() >= floatJumps.size());
CHECK(jumps.size() == coeffs.size());
SFIZZ_CHECK(jumps.size() >= floatJumps.size());
SFIZZ_CHECK(jumps.size() == coeffs.size());
auto floatJump = floatJumps.data();
auto jump = jumps.data();

View file

@ -24,6 +24,7 @@
sfz::Synth::Synth()
: Synth(config::numVoices)
{
initializeSIMDDispatchers();
}
sfz::Synth::Synth(int numVoices)
@ -524,7 +525,7 @@ float sfz::Synth::getTuningFrequency() const
void sfz::Synth::loadStretchTuningByRatio(float ratio)
{
CHECK(ratio >= 0.0f && ratio <= 1.0f);
SFIZZ_CHECK(ratio >= 0.0f && ratio <= 1.0f);
ratio = clamp(ratio, 0.0f, 1.0f);
if (ratio > 0.0f)
@ -747,8 +748,8 @@ void sfz::Synth::renderBlock(AudioSpan<float> buffer) noexcept
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
ASSERT(!hasNanInf(buffer.getConstSpan(1)));
CHECK(isReasonableAudio(buffer.getConstSpan(0)));
CHECK(isReasonableAudio(buffer.getConstSpan(1)));
SFIZZ_CHECK(isReasonableAudio(buffer.getConstSpan(0)));
SFIZZ_CHECK(isReasonableAudio(buffer.getConstSpan(1)));
}
void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept
@ -1129,14 +1130,14 @@ int sfz::Synth::getSampleQuality(ProcessMode mode)
case ProcessFreewheeling:
return resources.synthConfig.freeWheelingSampleQuality;
default:
CHECK(false);
SFIZZ_CHECK(false);
return 0;
}
}
void sfz::Synth::setSampleQuality(ProcessMode mode, int quality)
{
CHECK(quality >= 1 && quality <= 10);
SFIZZ_CHECK(quality >= 1 && quality <= 10);
quality = clamp(quality, 1, 10);
switch (mode) {
@ -1147,7 +1148,7 @@ void sfz::Synth::setSampleQuality(ProcessMode mode, int quality)
resources.synthConfig.freeWheelingSampleQuality = quality;
break;
default:
CHECK(false);
SFIZZ_CHECK(false);
break;
}
}

View file

@ -264,8 +264,8 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
#if 0
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
ASSERT(!hasNanInf(buffer.getConstSpan(1)));
CHECK(isReasonableAudio(buffer.getConstSpan(0)));
CHECK(isReasonableAudio(buffer.getConstSpan(1)));
SFIZZ_CHECK(isReasonableAudio(buffer.getConstSpan(0)));
SFIZZ_CHECK(isReasonableAudio(buffer.getConstSpan(1)));
#endif
}
@ -282,7 +282,7 @@ void sfz::Voice::amplitudeEnvelope(absl::Span<float> modulationSpan) noexcept
egEnvelope.getBlock(modulationSpan);
// Amplitude envelope
applyGain<float>(baseGain, modulationSpan);
applyGain1<float>(baseGain, modulationSpan);
for (const auto& mod : region->amplitudeCC) {
linearModifier(resources, *tempSpan, mod, normalizePercents<float>);
applyGain<float>(*tempSpan, modulationSpan);
@ -305,7 +305,7 @@ void sfz::Voice::amplitudeEnvelope(absl::Span<float> modulationSpan) noexcept
}
// Volume envelope
applyGain<float>(db2mag(baseVolumedB), modulationSpan);
applyGain1<float>(db2mag(baseVolumedB), modulationSpan);
for (const auto& mod : region->volumeCC) {
multiplicativeModifier(resources, *tempSpan, mod, [](float x) {
return db2mag(x);
@ -480,7 +480,7 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
jumps->front() += floatPositionOffset;
cumsum<float>(*jumps, *jumps);
sfzInterpolationCast<float>(*jumps, *indices, *coeffs);
add<int>(sourcePosition, *indices);
add1<int>(sourcePosition, *indices);
if (region->shouldLoop() && region->loopEnd(currentPromise->oversamplingFactor) <= source.getNumFrames()) {
const auto loopEnd = static_cast<int>(region->loopEnd(currentPromise->oversamplingFactor));
@ -488,7 +488,7 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
for (auto* index = indices->begin(); index < indices->end(); ++index) {
if (*index > loopEnd) {
const auto remainingElements = static_cast<size_t>(std::distance(index, indices->end()));
subtract<int>(offset, { index, remainingElements });
subtract1<int>(offset, { index, remainingElements });
}
}
} else {
@ -542,8 +542,8 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
#if 0
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
ASSERT(!hasNanInf(buffer.getConstSpan(1)));
CHECK(isReasonableAudio(buffer.getConstSpan(0)));
CHECK(isReasonableAudio(buffer.getConstSpan(1)));
SFIZZ_CHECK(isReasonableAudio(buffer.getConstSpan(0)));
SFIZZ_CHECK(isReasonableAudio(buffer.getConstSpan(1)));
#endif
}
@ -624,8 +624,8 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
for (unsigned i = 0, n = waveUnisonSize; i < n; ++i) {
WavetableOscillator& osc = waveOscillators[i];
osc.processModulated(frequencies->data(), waveDetuneRatio[i], tempSpan->data(), numFrames);
sfz::multiplyAdd<float>(waveLeftGain[i], *tempSpan, leftSpan);
sfz::multiplyAdd<float>(waveRightGain[i], *tempSpan, rightSpan);
multiplyAdd1<float>(waveLeftGain[i], *tempSpan, leftSpan);
multiplyAdd1<float>(waveRightGain[i], *tempSpan, rightSpan);
}
}
}
@ -633,8 +633,8 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
#if 0
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
ASSERT(!hasNanInf(buffer.getConstSpan(1)));
CHECK(isReasonableAudio(buffer.getConstSpan(0)));
CHECK(isReasonableAudio(buffer.getConstSpan(1)));
SFIZZ_CHECK(isReasonableAudio(buffer.getConstSpan(0)));
SFIZZ_CHECK(isReasonableAudio(buffer.getConstSpan(1)));
#endif
}

View file

@ -103,8 +103,8 @@ namespace fx {
// mix down the stereo signal to create the resonator excitation source
absl::Span<float> resInput = _tempBuffer.getSpan(0).first(nframes);
sfz::applyGain<float>(M_SQRT1_2, inputL, resInput);
sfz::multiplyAdd<float>(M_SQRT1_2, inputR, resInput);
sfz::applyGain1<float>(M_SQRT1_2, inputL, resInput);
sfz::multiplyAdd1<float>(M_SQRT1_2, inputR, resInput);
// generate the strings summed into a common buffer
absl::Span<float> resOutput = _tempBuffer.getSpan(1).first(nframes);

View file

@ -16,7 +16,7 @@ constexpr unsigned TypeAlignment = 8;
constexpr unsigned ByteAlignment = TypeAlignment * sizeof(Type);
#endif
void applyGainAVX(float gain, const float* input, float* output, unsigned size) noexcept
void gain1AVX(float gain, const float* input, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;
@ -36,7 +36,7 @@ void applyGainAVX(float gain, const float* input, float* output, unsigned size)
*output++ = gain * (*input++);
}
void applyGainAVX(const float* gain, const float* input, float* output, unsigned size) noexcept
void gainAVX(const float* gain, const float* input, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;

View file

@ -6,5 +6,5 @@
#pragma once
void applyGainAVX(float gain, const float* input, float* output, unsigned size) noexcept;
void applyGainAVX(const float* gain, const float* input, float* output, unsigned size) noexcept;
void gain1AVX(float gain, const float* input, float* output, unsigned size) noexcept;
void gainAVX(const float* gain, const float* input, float* output, unsigned size) noexcept;

View file

@ -82,7 +82,7 @@ void writeInterleavedSSE(const float* inputLeft, const float* inputRight, float*
}
}
void applyGainSSE(float gain, const float* input, float* output, unsigned size) noexcept
void gain1SSE(float gain, const float* input, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;
@ -102,7 +102,7 @@ void applyGainSSE(float gain, const float* input, float* output, unsigned size)
*output++ = gain * (*input++);
}
void applyGainSSE(const float* gain, const float* input, float* output, unsigned size) noexcept
void gainSSE(const float* gain, const float* input, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;
@ -161,7 +161,7 @@ void multiplyAddSSE(const float* gain, const float* input, float* output, unsign
*output++ += (*gain++) * (*input++);
}
void multiplyAddSSE(float gain, const float* input, float* output, unsigned size) noexcept
void multiplyAdd1SSE(float gain, const float* input, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;
@ -260,7 +260,7 @@ void addSSE(const float* input, float* output, unsigned size) noexcept
*output++ += *input++;
}
void addSSE(float value, float* output, unsigned size) noexcept
void add1SSE(float value, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;
@ -299,7 +299,7 @@ void subtractSSE(const float* input, float* output, unsigned size) noexcept
*output++ -= *input++;
}
void subtractSSE(float value, float* output, unsigned size) noexcept
void subtract1SSE(float value, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;

View file

@ -9,17 +9,17 @@
/* These are the SSE versions of the SIMDHelpers */
void readInterleavedSSE(const float* input, float* outputLeft, float* outputRight, unsigned inputSize) noexcept;
void writeInterleavedSSE(const float* inputLeft, const float* inputRight, float* output, unsigned outputSize) noexcept;
void applyGainSSE(float gain, const float* input, float* output, unsigned size) noexcept;
void applyGainSSE(const float* gain, const float* input, float* output, unsigned size) noexcept;
void gainSSE(const float* gain, const float* input, float* output, unsigned size) noexcept;
void gain1SSE(float gain, const float* input, float* output, unsigned size) noexcept;
void divideSSE(const float* input, const float* divisor, float* output, unsigned size) noexcept;
void multiplyAddSSE(const float* gain, const float* input, float* output, unsigned size) noexcept;
void multiplyAddSSE(float gain, const float* input, float* output, unsigned size) noexcept;
void multiplyAdd1SSE(float gain, const float* input, float* output, unsigned size) noexcept;
float linearRampSSE(float* output, float start, float step, unsigned size) noexcept;
float multiplicativeRampSSE(float* output, float start, float step, unsigned size) noexcept;
void addSSE(const float* input, float* output, unsigned size) noexcept;
void addSSE(float value, float* output, unsigned size) noexcept;
void add1SSE(float value, float* output, unsigned size) noexcept;
void subtractSSE(const float* input, float* output, unsigned size) noexcept;
void subtractSSE(float value, float* output, unsigned size) noexcept;
void subtract1SSE(float value, float* output, unsigned size) noexcept;
void copySSE(const float* input, float* output, unsigned size) noexcept;
float meanSSE(const float* vector, unsigned size) noexcept;
float meanSquaredSSE(const float* vector, unsigned size) noexcept;

View file

@ -28,7 +28,7 @@ inline void writeInterleavedScalar(const T* inputLeft, const T* inputRight, T* o
}
template<class T>
inline void applyGainScalar(T gain, const T* input, T* output, unsigned size) noexcept
inline void gain1Scalar(T gain, const T* input, T* output, unsigned size) noexcept
{
const auto sentinel = output + size;
while (output < sentinel)
@ -36,7 +36,7 @@ inline void applyGainScalar(T gain, const T* input, T* output, unsigned size) no
}
template<class T>
inline void applyGainScalar(const T* gain, const T* input, T* output, unsigned size) noexcept
inline void gainScalar(const T* gain, const T* input, T* output, unsigned size) noexcept
{
const auto sentinel = output + size;
while (output < sentinel)
@ -60,7 +60,7 @@ inline void multiplyAddScalar(const T* gain, const T* input, T* output, unsigned
}
template <class T>
inline void multiplyAddScalar(T gain, const T* input, T* output, unsigned size) noexcept
inline void multiplyAdd1Scalar(T gain, const T* input, T* output, unsigned size) noexcept
{
const auto sentinel = output + size;
while (output < sentinel)
@ -98,7 +98,7 @@ inline void addScalar(const T* input, T* output, unsigned size) noexcept
}
template <class T>
inline void addScalar(T value, T* output, unsigned size) noexcept
inline void add1Scalar(T value, T* output, unsigned size) noexcept
{
const auto sentinel = output + size;
while (output < sentinel)
@ -114,7 +114,7 @@ inline void subtractScalar(const T* input, T* output, unsigned size) noexcept
}
template <class T>
inline void subtractScalar(T value, T* output, unsigned size) noexcept
inline void subtract1Scalar(T value, T* output, unsigned size) noexcept
{
const auto sentinel = output + size;
while (output < sentinel)

View file

@ -5,8 +5,6 @@
int main(int argc, char* argv[])
{
sfz::SIMDInitializer simdInit;
int result = Catch::Session().run(argc, argv);
return result;
}

View file

@ -55,7 +55,7 @@ TEST_CASE("[Helpers] Interleaved read")
std::array<float, 16> expected { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 8> leftOutput;
std::array<float, 8> rightOutput;
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, false);
sfz::readInterleaved(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 16> real;
@ -73,7 +73,7 @@ TEST_CASE("[Helpers] Interleaved read unaligned end")
std::array<float, 20> expected { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f };
std::array<float, 10> leftOutput;
std::array<float, 10> rightOutput;
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, false);
sfz::readInterleaved(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 20> real;
@ -91,7 +91,7 @@ TEST_CASE("[Helpers] Small interleaved read unaligned end")
std::array<float, 6> expected { 0.0f, 1.0f, 2.0f, 10.0f, 11.0f, 12.0f };
std::array<float, 3> leftOutput;
std::array<float, 3> rightOutput;
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, false);
sfz::readInterleaved(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 6> real;
@ -109,7 +109,7 @@ TEST_CASE("[Helpers] Interleaved read -- SIMD")
std::array<float, 16> expected = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 8> leftOutput;
std::array<float, 8> rightOutput;
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, true);
sfz::readInterleaved(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 16> real;
@ -127,7 +127,7 @@ TEST_CASE("[Helpers] Interleaved read unaligned end -- SIMD")
std::array<float, 20> expected = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f };
std::array<float, 10> leftOutput;
std::array<float, 10> rightOutput;
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, true);
sfz::readInterleaved(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 20> real;
@ -145,7 +145,7 @@ TEST_CASE("[Helpers] Small interleaved read unaligned end -- SIMD")
std::array<float, 6> expected { 0.0f, 1.0f, 2.0f, 10.0f, 11.0f, 12.0f };
std::array<float, 3> leftOutput;
std::array<float, 3> rightOutput;
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, true);
sfz::readInterleaved(input, absl::MakeSpan(leftOutput), absl::MakeSpan(rightOutput));
std::array<float, 6> real;
@ -165,9 +165,9 @@ TEST_CASE("[Helpers] Interleaved read SIMD vs Scalar")
std::array<float, medBufferSize> leftOutputSIMD;
std::array<float, medBufferSize> rightOutputSIMD;
std::iota(input.begin(), input.end(), 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, false);
sfz::readInterleaved(input, absl::MakeSpan(leftOutputScalar), absl::MakeSpan(rightOutputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::readInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::readInterleaved, true);
sfz::readInterleaved(input, absl::MakeSpan(leftOutputSIMD), absl::MakeSpan(rightOutputSIMD));
REQUIRE(leftOutputScalar == leftOutputSIMD);
REQUIRE(rightOutputScalar == rightOutputSIMD);
@ -188,7 +188,7 @@ TEST_CASE("[Helpers] Interleaved write")
std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 16> output;
std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, false);
sfz::writeInterleaved(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -199,7 +199,7 @@ TEST_CASE("[Helpers] Interleaved write unaligned end")
std::array<float, 10> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f };
std::array<float, 20> output;
std::array<float, 20> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f, 8.0f, 18.0f, 9.0f, 19.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, false);
sfz::writeInterleaved(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -210,7 +210,7 @@ TEST_CASE("[Helpers] Small interleaved write unaligned end")
std::array<float, 3> rightInput { 10.0f, 11.0f, 12.0f };
std::array<float, 6> output;
std::array<float, 6> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, false);
sfz::writeInterleaved(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -230,7 +230,7 @@ TEST_CASE("[Helpers] Interleaved write -- SIMD")
std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 16> output;
std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, true);
sfz::writeInterleaved(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -251,7 +251,7 @@ TEST_CASE("[Helpers] Small interleaved write unaligned end -- SIMD")
std::array<float, 3> rightInput { 10.0f, 11.0f, 12.0f };
std::array<float, 6> output;
std::array<float, 6> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, true);
sfz::writeInterleaved(leftInput, rightInput, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -264,9 +264,9 @@ TEST_CASE("[Helpers] Interleaved write SIMD vs Scalar")
std::array<float, medBufferSize * 2> outputSIMD;
std::iota(leftInput.begin(), leftInput.end(), 0.0f);
std::iota(rightInput.begin(), rightInput.end(), static_cast<float>(medBufferSize));
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, false);
sfz::writeInterleaved(leftInput, rightInput, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::writeInterleaved, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::writeInterleaved, true);
sfz::writeInterleaved(leftInput, rightInput, absl::MakeSpan(outputSIMD));
REQUIRE(outputScalar == outputSIMD);
}
@ -281,16 +281,16 @@ TEST_CASE("[Helpers] Gain, single")
SECTION("Scalar")
{
std::array<float, 65> output;
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(fillValue, input, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain1, false);
sfz::applyGain1<float>(fillValue, input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
SECTION("SIMD")
{
std::array<float, 65> output;
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
sfz::applyGain<float>(fillValue, input, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain1, true);
sfz::applyGain1<float>(fillValue, input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
}
@ -303,15 +303,15 @@ TEST_CASE("[Helpers] Gain, single and inplace")
SECTION("Scalar")
{
absl::c_fill(buffer, 1.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(fillValue, buffer, absl::MakeSpan(buffer));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain1, false);
sfz::applyGain1<float>(fillValue, buffer, absl::MakeSpan(buffer));
REQUIRE(buffer == expected);
}
SECTION("SIMD")
{
absl::c_fill(buffer, 1.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(fillValue, buffer, absl::MakeSpan(buffer));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain1, false);
sfz::applyGain1<float>(fillValue, buffer, absl::MakeSpan(buffer));
REQUIRE(buffer == expected);
}
}
@ -328,7 +328,7 @@ TEST_CASE("[Helpers] Gain, spans")
SECTION("Scalar")
{
std::array<float, 65> output;
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -336,7 +336,7 @@ TEST_CASE("[Helpers] Gain, spans")
SECTION("SIMD")
{
std::array<float, 65> output;
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain, true);
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -353,7 +353,7 @@ TEST_CASE("[Helpers] Gain, spans and inplace")
SECTION("Scalar")
{
absl::c_fill(buffer, 1.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(gain, buffer, absl::MakeSpan(buffer));
REQUIRE(buffer == expected);
}
@ -361,7 +361,7 @@ TEST_CASE("[Helpers] Gain, spans and inplace")
SECTION("SIMD")
{
absl::c_fill(buffer, 1.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::gain, false);
sfz::applyGain<float>(gain, buffer, absl::MakeSpan(buffer));
REQUIRE(buffer == expected);
}
@ -373,7 +373,7 @@ TEST_CASE("[Helpers] Linear Ramp")
const float v { fillValue };
std::array<float, 6> output;
std::array<float, 6> expected { start, start + v, start + v + v, start + v + v + v, start + v + v + v + v, start + v + v + v + v + v };
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, false);
sfz::linearRamp<float>(absl::MakeSpan(output), start, v);
REQUIRE(output == expected);
}
@ -384,7 +384,7 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD)")
const float v { fillValue };
std::array<float, 6> output;
std::array<float, 6> expected { start, start + v, start + v + v, start + v + v + v, start + v + v + v + v, start + v + v + v + v + v };
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
sfz::linearRamp<float>(absl::MakeSpan(output), start, v);
REQUIRE(approxEqual<float>(output, expected));
}
@ -394,9 +394,9 @@ TEST_CASE("[Helpers] Linear Ramp (SIMD vs scalar)")
const float start { 0.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, false);
sfz::linearRamp<float>(absl::MakeSpan(outputScalar), start, fillValue);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
sfz::linearRamp<float>(absl::MakeSpan(outputSIMD), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -406,9 +406,9 @@ TEST_CASE("[Helpers] Linear Ramp unaligned (SIMD vs scalar)")
const float start { 0.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, false);
sfz::linearRamp<float>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
sfz::linearRamp<float>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -419,7 +419,7 @@ TEST_CASE("[Helpers] Multiplicative Ramp")
const float v { fillValue };
std::array<float, 6> output;
std::array<float, 6> expected { start, start * v, start * v * v, start * v * v * v, start * v * v * v * v, start * v * v * v * v * v };
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, false);
sfz::multiplicativeRamp<float>(absl::MakeSpan(output), start, v);
REQUIRE(approxEqual<float>(output, expected));
}
@ -430,7 +430,7 @@ TEST_CASE("[Helpers] Multiplicative Ramp (SIMD)")
const float v { fillValue };
std::array<float, 6> output;
std::array<float, 6> expected { start, start * v, start * v * v, start * v * v * v, start * v * v * v * v, start * v * v * v * v * v };
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, true);
sfz::multiplicativeRamp<float>(absl::MakeSpan(output), start, v);
REQUIRE(approxEqual<float>(output, expected));
}
@ -440,9 +440,9 @@ TEST_CASE("[Helpers] Multiplicative Ramp (SIMD vs scalar)")
const float start { 1.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, false);
sfz::multiplicativeRamp<float>(absl::MakeSpan(outputScalar), start, fillValue);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, true);
sfz::multiplicativeRamp<float>(absl::MakeSpan(outputSIMD), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -452,9 +452,9 @@ TEST_CASE("[Helpers] Multiplicative Ramp unaligned (SIMD vs scalar)")
const float start { 1.0f };
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, false);
sfz::multiplicativeRamp<float>(absl::MakeSpan(outputScalar).subspan(1), start, fillValue);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplicativeRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplicativeRamp, true);
sfz::multiplicativeRamp<float>(absl::MakeSpan(outputSIMD).subspan(1), start, fillValue);
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -464,7 +464,7 @@ TEST_CASE("[Helpers] Add")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::add, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add, false);
sfz::add<float>(input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -474,7 +474,7 @@ TEST_CASE("[Helpers] Add (SIMD)")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::add, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add, true);
sfz::add<float>(input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -488,9 +488,9 @@ TEST_CASE("[Helpers] Add (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0f);
absl::c_fill(outputSIMD, 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::add, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add, false);
sfz::add<float>(input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::add, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::add, true);
sfz::add<float>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -501,7 +501,7 @@ TEST_CASE("[Helpers] MultiplyAdd (Scalar)")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f };
std::array<float, 5> expected { 5.0f, 4.2f, 3.6f, 3.2f, 3.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd, false);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -512,7 +512,7 @@ TEST_CASE("[Helpers] MultiplyAdd (SIMD)")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f };
std::array<float, 5> expected { 5.0f, 4.2f, 3.6f, 3.2f, 3.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd, true);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -528,9 +528,9 @@ TEST_CASE("[Helpers] MultiplyAdd (SIMD vs scalar)")
absl::c_iota(outputScalar, 0.0f);
absl::c_iota(outputSIMD, 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd, false);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd, true);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -541,8 +541,8 @@ TEST_CASE("[Helpers] MultiplyAdd fixed gain (Scalar)")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f };
std::array<float, 5> expected { 5.3f, 4.6f, 3.9f, 3.2f, 2.5f };
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, false);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd1, false);
sfz::multiplyAdd1<float>(gain, input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -552,8 +552,8 @@ TEST_CASE("[Helpers] MultiplyAdd fixed gain (SIMD)")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f };
std::array<float, 5> expected { 5.3f, 4.6f, 3.9f, 3.2f, 2.5f };
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, true);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd1, true);
sfz::multiplyAdd1<float>(gain, input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -567,10 +567,10 @@ TEST_CASE("[Helpers] MultiplyAdd fixed gain (SIMD vs scalar)")
absl::c_iota(outputScalar, 0.0f);
absl::c_iota(outputSIMD, 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, false);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::multiplyAdd, true);
sfz::multiplyAdd<float>(gain, input, absl::MakeSpan(outputSIMD));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd1, false);
sfz::multiplyAdd1<float>(gain, input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyAdd1, true);
sfz::multiplyAdd1<float>(gain, input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -587,8 +587,8 @@ TEST_CASE("[Helpers] Subtract 2")
{
std::array<float, 5> output { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> expected { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, false);
sfz::subtract<float>(1.0f, absl::MakeSpan(output));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract1, false);
sfz::subtract1<float>(1.0f, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -598,7 +598,7 @@ TEST_CASE("[Helpers] Subtract (SIMD)")
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
std::array<float, 5> expected { 0.0f, -1.0f, -2.0f, -3.0f, -4.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract, true);
sfz::subtract<float>(input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -612,9 +612,9 @@ TEST_CASE("[Helpers] Subtract (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0f);
absl::c_fill(outputSIMD, 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract, false);
sfz::subtract<float>(input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract, true);
sfz::subtract<float>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -626,10 +626,10 @@ TEST_CASE("[Helpers] Subtract 2 (SIMD vs scalar)")
absl::c_iota(outputScalar, 0.0f);
absl::c_iota(outputSIMD, 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, false);
sfz::subtract<float>(1.2f, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::subtract, true);
sfz::subtract<float>(1.2f, absl::MakeSpan(outputSIMD));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract1, false);
sfz::subtract1<float>(1.2f, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::subtract1, true);
sfz::subtract1<float>(1.2f, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -637,7 +637,7 @@ TEST_CASE("[Helpers] copy")
{
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::copy, false);
sfz::copy<float>(input, absl::MakeSpan(output));
REQUIRE(output == input);
}
@ -646,7 +646,7 @@ TEST_CASE("[Helpers] copy (SIMD)")
{
std::array<float, 5> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
std::array<float, 5> output { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::copy, true);
sfz::copy<float>(input, absl::MakeSpan(output));
REQUIRE(output == input);
}
@ -660,9 +660,9 @@ TEST_CASE("[Helpers] copy (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0f);
absl::c_fill(outputSIMD, 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::copy, false);
sfz::copy<float>(input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::copy, true);
sfz::copy<float>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -670,9 +670,9 @@ TEST_CASE("[Helpers] copy (SIMD vs scalar)")
TEST_CASE("[Helpers] Mean")
{
std::array<float, 10> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::mean, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::mean, false);
REQUIRE(sfz::mean<float>(input) == 5.5f);
sfz::setSIMDOpStatus(sfz::SIMDOps::mean, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::mean, true);
REQUIRE(sfz::mean<float>(input) == 5.5f);
}
@ -680,9 +680,9 @@ TEST_CASE("[Helpers] Mean (SIMD vs scalar)")
{
std::vector<float> input(bigBufferSize);
absl::c_iota(input, 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::mean, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::mean, false);
auto scalarResult = sfz::mean<float>(input);
sfz::setSIMDOpStatus(sfz::SIMDOps::mean, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::mean, true);
auto simdResult = sfz::mean<float>(input);
REQUIRE( scalarResult == Approx(simdResult).margin(1e-3) );
}
@ -690,9 +690,9 @@ TEST_CASE("[Helpers] Mean (SIMD vs scalar)")
TEST_CASE("[Helpers] Mean Squared")
{
std::array<float, 10> input { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f };
sfz::setSIMDOpStatus(sfz::SIMDOps::meanSquared, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, false);
REQUIRE(sfz::meanSquared<float>(input) == 38.5f);
sfz::setSIMDOpStatus(sfz::SIMDOps::meanSquared, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, true);
REQUIRE(sfz::meanSquared<float>(input) == 38.5f);
}
@ -700,9 +700,9 @@ TEST_CASE("[Helpers] Mean Squared (SIMD vs scalar)")
{
std::vector<float> input(medBufferSize);
absl::c_iota(input, 0.0f);
sfz::setSIMDOpStatus(sfz::SIMDOps::meanSquared, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, false);
auto scalarResult = sfz::meanSquared<float>(input);
sfz::setSIMDOpStatus(sfz::SIMDOps::meanSquared, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, true);
auto simdResult = sfz::meanSquared<float>(input);
REQUIRE( scalarResult == Approx(simdResult).margin(1e-3) );
}
@ -712,7 +712,7 @@ TEST_CASE("[Helpers] Cumulative sum")
std::array<float, 6> input { 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f }; // 1.1 2.3 3.6 5.0f 6.5 8.1
std::array<float, 6> output;
std::array<float, 6> expected { 1.1f, 2.3f, 3.6f, 5.0f, 6.5f, 8.1f };
sfz::setSIMDOpStatus(sfz::SIMDOps::cumsum, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::cumsum, false);
sfz::cumsum<float>(input, absl::MakeSpan(output));
REQUIRE(approxEqual<float>(output, expected));
}
@ -722,11 +722,11 @@ TEST_CASE("[Helpers] Cumulative sum (SIMD vs Scalar)")
std::vector<float> input(bigBufferSize);
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
sfz::linearRamp<float>(absl::MakeSpan(input), 0.0f, 0.1f);
sfz::setSIMDOpStatus(sfz::SIMDOps::cumsum, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::cumsum, false);
sfz::cumsum<float>(input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::cumsum, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::cumsum, true);
sfz::cumsum<float>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -736,7 +736,7 @@ TEST_CASE("[Helpers] Diff")
std::array<float, 6> input { 1.1f, 2.3f, 3.6f, 5.0f, 6.5f, 8.1f };
std::array<float, 6> output;
std::array<float, 6> expected { 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f };
sfz::setSIMDOpStatus(sfz::SIMDOps::diff, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::diff, false);
sfz::diff<float>(input, absl::MakeSpan(output));
REQUIRE(approxEqual<float>(output, expected));
}
@ -746,11 +746,11 @@ TEST_CASE("[Helpers] Diff (SIMD vs Scalar)")
std::vector<float> input(bigBufferSize);
std::vector<float> outputScalar(bigBufferSize);
std::vector<float> outputSIMD(bigBufferSize);
sfz::setSIMDOpStatus(sfz::SIMDOps::linearRamp, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::linearRamp, true);
sfz::linearRamp<float>(absl::MakeSpan(input), 0.0f, 0.1f);
sfz::setSIMDOpStatus(sfz::SIMDOps::diff, false);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::diff, false);
sfz::diff<float>(input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::diff, true);
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::diff, true);
sfz::diff<float>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}