Example AVX for the applyGain case
It does not help so much though apparently, at least on my machine...
This commit is contained in:
parent
ccfbf3cd1c
commit
a6417f27c4
3 changed files with 101 additions and 65 deletions
|
|
@ -13,6 +13,7 @@ macro(sfizz_add_simd_sources SOURCES_VAR PREFIX)
|
||||||
set_source_files_properties(
|
set_source_files_properties(
|
||||||
${PREFIX}/sfizz/effects/impl/ResonantStringAVX.cpp
|
${PREFIX}/sfizz/effects/impl/ResonantStringAVX.cpp
|
||||||
${PREFIX}/sfizz/effects/impl/ResonantArrayAVX.cpp
|
${PREFIX}/sfizz/effects/impl/ResonantArrayAVX.cpp
|
||||||
|
${PREFIX}/sfizz/SIMDHelpers.cpp
|
||||||
PROPERTIES COMPILE_FLAGS "-mavx")
|
PROPERTIES COMPILE_FLAGS "-mavx")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include "SIMDConfig.h"
|
#include "SIMDConfig.h"
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
#include <xmmintrin.h>
|
#include <immintrin.h>
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -149,7 +149,17 @@ void applyGain<float>(float gain, const float* input, float* output, unsigned si
|
||||||
|
|
||||||
if (getSIMDOpStatus(SIMDOps::gain)) {
|
if (getSIMDOpStatus(SIMDOps::gain)) {
|
||||||
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
|
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
|
||||||
if (cpuInfo.has_sse()) {
|
if (cpuInfo.has_avx()) {
|
||||||
|
const auto* lastAligned = prevAligned<32>(sentinel);
|
||||||
|
const auto mmGain = _mm256_set1_ps(gain);
|
||||||
|
while (unaligned<32>(input, output) && output < lastAligned)
|
||||||
|
*output++ = gain * (*input++);
|
||||||
|
|
||||||
|
while (output < lastAligned) {
|
||||||
|
_mm256_store_ps(output, _mm256_mul_ps(mmGain, _mm256_load_ps(input)));
|
||||||
|
incrementAll<8>(input, output);
|
||||||
|
}
|
||||||
|
} else if (cpuInfo.has_sse()) {
|
||||||
const auto* lastAligned = prevAligned(sentinel);
|
const auto* lastAligned = prevAligned(sentinel);
|
||||||
const auto mmGain = _mm_set1_ps(gain);
|
const auto mmGain = _mm_set1_ps(gain);
|
||||||
while (unaligned(input, output) && output < lastAligned)
|
while (unaligned(input, output) && output < lastAligned)
|
||||||
|
|
@ -175,7 +185,16 @@ void applyGain<float>(const float* gain, const float* input, float* output, unsi
|
||||||
|
|
||||||
if (getSIMDOpStatus(SIMDOps::gain)) {
|
if (getSIMDOpStatus(SIMDOps::gain)) {
|
||||||
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
|
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
|
||||||
if (cpuInfo.has_sse()) {
|
if (cpuInfo.has_avx()) {
|
||||||
|
const auto* lastAligned = prevAligned<32>(sentinel);
|
||||||
|
while (unaligned<32>(input, output) && output < lastAligned)
|
||||||
|
*output++ = (*gain++) * (*input++);
|
||||||
|
|
||||||
|
while (output < lastAligned) {
|
||||||
|
_mm256_store_ps(output, _mm256_mul_ps(_mm256_load_ps(gain), _mm256_load_ps(input)));
|
||||||
|
incrementAll<8>(input, output);
|
||||||
|
}
|
||||||
|
} else if (cpuInfo.has_sse()) {
|
||||||
const auto* lastAligned = prevAligned(sentinel);
|
const auto* lastAligned = prevAligned(sentinel);
|
||||||
|
|
||||||
while (unaligned(input, output) && output < lastAligned)
|
while (unaligned(input, output) && output < lastAligned)
|
||||||
|
|
|
||||||
|
|
@ -273,82 +273,98 @@ TEST_CASE("[Helpers] Interleaved write SIMD vs Scalar")
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Gain, single")
|
TEST_CASE("[Helpers] Gain, single")
|
||||||
{
|
{
|
||||||
std::array<float, 5> input { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
std::array<float, 65> input;
|
||||||
std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
std::array<float, 65> expected;
|
||||||
std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
|
absl::c_fill(input, 1.0f);
|
||||||
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
absl::c_fill(expected, fillValue);
|
||||||
sfz::applyGain<float>(fillValue, input, absl::MakeSpan(output));
|
|
||||||
REQUIRE(output == expected);
|
SECTION("Scalar")
|
||||||
|
{
|
||||||
|
std::array<float, 65> output;
|
||||||
|
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
||||||
|
sfz::applyGain<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));
|
||||||
|
REQUIRE(output == expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Gain, single and inplace")
|
TEST_CASE("[Helpers] Gain, single and inplace")
|
||||||
{
|
{
|
||||||
std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
std::array<float, 65> expected;
|
||||||
std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
|
std::array<float, 65> buffer;
|
||||||
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
absl::c_fill(expected, fillValue);
|
||||||
sfz::applyGain<float>(fillValue, buffer, absl::MakeSpan(buffer));
|
SECTION("Scalar")
|
||||||
REQUIRE(buffer == expected);
|
{
|
||||||
|
absl::c_fill(buffer, 1.0f);
|
||||||
|
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
||||||
|
sfz::applyGain<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));
|
||||||
|
REQUIRE(buffer == expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Gain, spans")
|
TEST_CASE("[Helpers] Gain, spans")
|
||||||
{
|
{
|
||||||
std::array<float, 5> input { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
std::array<float, 65> input;
|
||||||
std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
|
std::array<float, 65> gain;
|
||||||
std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
std::array<float, 65> expected;
|
||||||
std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
|
absl::c_fill(input, 1.0f);
|
||||||
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
absl::c_iota(gain, 1.0f);
|
||||||
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
|
absl::c_iota(expected, 1.0f);
|
||||||
REQUIRE(output == expected);
|
|
||||||
|
SECTION("Scalar")
|
||||||
|
{
|
||||||
|
std::array<float, 65> output;
|
||||||
|
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
||||||
|
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
|
||||||
|
REQUIRE(output == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("SIMD")
|
||||||
|
{
|
||||||
|
std::array<float, 65> output;
|
||||||
|
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
|
||||||
|
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
|
||||||
|
REQUIRE(output == expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Gain, spans and inplace")
|
TEST_CASE("[Helpers] Gain, spans and inplace")
|
||||||
{
|
{
|
||||||
std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
std::array<float, 65> buffer;
|
||||||
std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
|
std::array<float, 65> gain;
|
||||||
std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
|
std::array<float, 65> expected;
|
||||||
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
absl::c_iota(gain, 1.0f);
|
||||||
sfz::applyGain<float>(gain, buffer, absl::MakeSpan(buffer));
|
absl::c_iota(expected, 1.0f);
|
||||||
REQUIRE(buffer == expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Gain, single (SIMD)")
|
SECTION("Scalar")
|
||||||
{
|
{
|
||||||
std::array<float, 5> input { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
absl::c_fill(buffer, 1.0f);
|
||||||
std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
||||||
std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
|
sfz::applyGain<float>(gain, buffer, absl::MakeSpan(buffer));
|
||||||
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
|
REQUIRE(buffer == expected);
|
||||||
sfz::applyGain<float>(fillValue, input, absl::MakeSpan(output));
|
}
|
||||||
REQUIRE(output == expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Gain, single and inplace (SIMD)")
|
SECTION("SIMD")
|
||||||
{
|
{
|
||||||
std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
absl::c_fill(buffer, 1.0f);
|
||||||
std::array<float, 5> expected { fillValue, fillValue, fillValue, fillValue, fillValue };
|
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, false);
|
||||||
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
|
sfz::applyGain<float>(gain, buffer, absl::MakeSpan(buffer));
|
||||||
sfz::applyGain<float>(fillValue, buffer, absl::MakeSpan(buffer));
|
REQUIRE(buffer == expected);
|
||||||
REQUIRE(buffer == expected);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Gain, spans (SIMD)")
|
|
||||||
{
|
|
||||||
std::array<float, 5> input { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
|
||||||
std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
|
|
||||||
std::array<float, 5> output { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
|
||||||
std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
|
|
||||||
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
|
|
||||||
sfz::applyGain<float>(gain, input, absl::MakeSpan(output));
|
|
||||||
REQUIRE(output == expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Gain, spans and inplace (SIMD)")
|
|
||||||
{
|
|
||||||
std::array<float, 5> buffer { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
|
||||||
std::array<float, 5> gain { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
|
|
||||||
std::array<float, 5> expected { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
|
|
||||||
sfz::setSIMDOpStatus(sfz::SIMDOps::gain, true);
|
|
||||||
sfz::applyGain<float>(gain, buffer, absl::MakeSpan(buffer));
|
|
||||||
REQUIRE(buffer == expected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Helpers] Linear Ramp")
|
TEST_CASE("[Helpers] Linear Ramp")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue