Move add to the new format

This commit is contained in:
Paul Ferrand 2020-05-31 09:24:44 +02:00 committed by Jean Pierre Cimalando
parent 8c6a01a066
commit 3cb8164068
5 changed files with 118 additions and 103 deletions

View file

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

View file

@ -145,7 +145,7 @@ void applyGain<float>(float gain, const float* input, float* output, unsigned si
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
if (cpuInfo.has_sse()) {
const auto* lastAligned = prevAligned(sentinel);
const auto mmGain = _mm_set_ps1(gain);
const auto mmGain = _mm_set1_ps(gain);
while (unaligned(input, output) && output < lastAligned)
*output++ = gain * (*input++);
@ -278,7 +278,7 @@ float linearRamp<float>(float* output, float start, float step, unsigned size) n
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
if (cpuInfo.has_sse()) {
const auto* lastAligned = prevAligned(sentinel);
while (unaligned(output) && output < lastAligned){
while (unaligned(output) && output < lastAligned) {
*output++ = start;
start += step;
}
@ -289,7 +289,7 @@ float linearRamp<float>(float* output, float start, float step, unsigned size) n
mmStart = _mm_add_ps(mmStart, mmStep);
_mm_store_ps(output, mmStart);
mmStart = _mm_shuffle_ps(mmStart, mmStart, _MM_SHUFFLE(3, 3, 3, 3));
incrementAll<4>( output);
incrementAll<4>(output);
}
start = _mm_cvtss_f32(mmStart) + step;
// fallthrough from lastAligned to sentinel
@ -313,7 +313,7 @@ float multiplicativeRamp<float>(float* output, float start, float step, unsigned
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
if (cpuInfo.has_sse()) {
const auto* lastAligned = prevAligned(sentinel);
while (unaligned(output) && output < lastAligned){
while (unaligned(output) && output < lastAligned) {
*output++ = start;
start *= step;
}
@ -324,7 +324,7 @@ float multiplicativeRamp<float>(float* output, float start, float step, unsigned
mmStart = _mm_mul_ps(mmStart, mmStep);
_mm_store_ps(output, mmStart);
mmStart = _mm_shuffle_ps(mmStart, mmStart, _MM_SHUFFLE(3, 3, 3, 3));
incrementAll<4>( output);
incrementAll<4>(output);
}
start = _mm_cvtss_f32(mmStart) * step;
// fallthrough from lastAligned to sentinel
@ -339,4 +339,57 @@ float multiplicativeRamp<float>(float* output, float start, float step, unsigned
return start;
}
template <>
void add<float>(const float* input, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;
if (getSIMDOpStatus(SIMDOps::add)) {
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
if (cpuInfo.has_sse()) {
const auto* lastAligned = prevAligned(sentinel);
while (unaligned(input, output) && output < lastAligned)
*output++ += *input++;
while (output < lastAligned) {
_mm_store_ps(output, _mm_add_ps(_mm_load_ps(output), _mm_load_ps(input)));
incrementAll<4>(input, output);
}
// fallthrough from lastAligned to sentinel
}
#endif
}
while (output < sentinel)
*output++ += *input++;
}
template <>
void add<float>(float value, float* output, unsigned size) noexcept
{
const auto sentinel = output + size;
if (getSIMDOpStatus(SIMDOps::add)) {
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
if (cpuInfo.has_sse()) {
const auto* lastAligned = prevAligned(sentinel);
while (unaligned(output) && output < lastAligned)
*output++ += value;
const auto mmValue = _mm_set1_ps(value);
while (output < lastAligned) {
_mm_store_ps(output, _mm_add_ps(_mm_load_ps(output), mmValue));
incrementAll<4>(output);
}
// fallthrough from lastAligned to sentinel
}
#endif
}
while (output < sentinel)
*output++ += value;
}
}

View file

@ -369,15 +369,6 @@ T linearRamp(absl::Span<T> output, T start, T step) noexcept
return linearRamp(output.data(), start, step, output.size());
}
namespace _internals {
template <class T>
inline void snippetRampMultiplicative(T*& output, T& value, T step)
{
*output++ = value;
value *= step;
}
}
/**
* @brief Compute a multiplicative ramp blockwise between 2 values
*
@ -408,55 +399,57 @@ T multiplicativeRamp(absl::Span<T> output, T start, T step) noexcept
}
namespace _internals {
template <class T>
inline void snippetAdd(const T*& input, T*& output)
{
*output++ += *input++;
}
template <class T>
inline void snippetAdd(const T value, T*& output)
{
*output++ += value;
}
}
/**
* @brief Add an input span to the output span
*
* The output size will be the minimum of the gain span, input span and output span sizes.
*
* @tparam T the underlying type
* @tparam SIMD use the SIMD version or the scalar version
* @param input
* @param output
* @param size
*/
template <class T, bool SIMD = SIMDConfig::add>
template <class T>
void add(const T* input, T* output, unsigned size) noexcept
{
const auto sentinel = output + size;
while (output < sentinel)
*output++ += *input++;
}
template <>
void add<float>(const float* input, float* output, unsigned size) noexcept;
template <class T>
void add(absl::Span<const T> input, absl::Span<T> output) noexcept
{
CHECK(output.size() >= input.size());
auto* in = input.begin();
auto* out = output.begin();
auto* sentinel = out + min(input.size(), output.size());
while (out < sentinel)
_internals::snippetAdd(in, out);
CHECK_SPAN_SIZES(input, output);
add<T>(input.data(), output.data(), minSpanSize(input, output));
}
/**
* @brief Add a value inplace
*
* @tparam T the underlying type
* @param value
* @param output
* @param size
*/
template <class T>
void add(T value, T* output, unsigned size) noexcept
{
const auto sentinel = output + size;
while (output < sentinel)
*output++ += value;
}
template <>
void add<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept;
void add<float>(float value, float* output, unsigned size) noexcept;
template <class T, bool SIMD = SIMDConfig::add>
template <class T>
void add(T value, absl::Span<T> output) noexcept
{
auto* out = output.begin();
auto* sentinel = output.end();
while (out < sentinel)
_internals::snippetAdd(value, out);
add<T>(value, output.data(), output.size());
}
template <>
void add<float, true>(float value, absl::Span<float> output) noexcept;
namespace _internals {
template <class T>
inline void snippetSubtract(const T*& input, T*& output)

View file

@ -16,49 +16,6 @@
constexpr uintptr_t TypeAlignment = 4;
template <>
void sfz::add<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{
CHECK(output.size() >= input.size());
auto* in = input.begin();
auto* out = output.begin();
auto* sentinel = out + min(input.size(), output.size());
const auto* lastAligned = prevAligned(sentinel);
while (unaligned(in, out) && out < lastAligned)
_internals::snippetAdd<float>(in, out);
while (out < lastAligned) {
_mm_store_ps(out, _mm_add_ps(_mm_load_ps(in), _mm_load_ps(out)));
incrementAll<TypeAlignment>(in, out);
}
while (out < sentinel)
_internals::snippetAdd<float>(in, out);
}
template <>
void sfz::add<float, true>(float value, absl::Span<float> output) noexcept
{
auto* out = output.begin();
auto* sentinel = output.end();
const auto* lastAligned = prevAligned(sentinel);
while (unaligned(out) && out < lastAligned)
_internals::snippetAdd<float>(value, out);
auto mmValue = _mm_set_ps1(value);
while (out < lastAligned) {
_mm_store_ps(out, _mm_add_ps(mmValue, _mm_load_ps(out)));
out += TypeAlignment;
}
while (out < sentinel)
_internals::snippetAdd<float>(value, out);
}
template <>
void sfz::subtract<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept
{

View file

@ -447,7 +447,8 @@ 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::add<float, false>(input, absl::MakeSpan(output));
sfz::setSIMDOpStatus(sfz::SIMDOps::add, false);
sfz::add<float>(input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -456,7 +457,8 @@ 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::add<float, true>(input, absl::MakeSpan(output));
sfz::setSIMDOpStatus(sfz::SIMDOps::add, true);
sfz::add<float>(input, absl::MakeSpan(output));
REQUIRE(output == expected);
}
@ -469,8 +471,10 @@ TEST_CASE("[Helpers] Add (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0f);
absl::c_fill(outputSIMD, 0.0f);
sfz::add<float, false>(input, absl::MakeSpan(outputScalar));
sfz::add<float, true>(input, absl::MakeSpan(outputSIMD));
sfz::setSIMDOpStatus(sfz::SIMDOps::add, false);
sfz::add<float>(input, absl::MakeSpan(outputScalar));
sfz::setSIMDOpStatus(sfz::SIMDOps::add, true);
sfz::add<float>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}
@ -631,8 +635,8 @@ TEST_CASE("[Helpers] copy (SIMD vs scalar)")
absl::c_fill(outputScalar, 0.0f);
absl::c_fill(outputSIMD, 0.0f);
sfz::add<float, false>(input, absl::MakeSpan(outputScalar));
sfz::add<float, true>(input, absl::MakeSpan(outputSIMD));
sfz::copy<float, false>(input, absl::MakeSpan(outputScalar));
sfz::copy<float, true>(input, absl::MakeSpan(outputSIMD));
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
}