Move copy to the new format
This commit is contained in:
parent
af855d3993
commit
190e7085de
5 changed files with 54 additions and 51 deletions
|
|
@ -43,14 +43,16 @@ BENCHMARK_DEFINE_F(CopyArray, StdCopy)(benchmark::State& state) {
|
|||
BENCHMARK_DEFINE_F(CopyArray, Scalar)(benchmark::State& state) {
|
||||
for (auto _ : state)
|
||||
{
|
||||
sfz::copy<float, false>(input, absl::MakeSpan(output));
|
||||
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, false);
|
||||
sfz::copy<float>(input, absl::MakeSpan(output));
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(CopyArray, SIMD)(benchmark::State& state) {
|
||||
for (auto _ : state)
|
||||
{
|
||||
sfz::copy<float, true>(input, absl::MakeSpan(output));
|
||||
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, true);
|
||||
sfz::copy<float>(input, absl::MakeSpan(output));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,14 +66,16 @@ BENCHMARK_DEFINE_F(CopyArray, StdCopy_Unaligned)(benchmark::State& state) {
|
|||
BENCHMARK_DEFINE_F(CopyArray, Scalar_Unaligned)(benchmark::State& state) {
|
||||
for (auto _ : state)
|
||||
{
|
||||
sfz::copy<float, false>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
|
||||
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, false);
|
||||
sfz::copy<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(CopyArray, SIMD_Unaligned)(benchmark::State& state) {
|
||||
for (auto _ : state)
|
||||
{
|
||||
sfz::copy<float, true>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
|
||||
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, true);
|
||||
sfz::copy<float>(absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -445,4 +445,30 @@ void subtract<float>(float value, float* output, unsigned size) noexcept
|
|||
*output++ -= value;
|
||||
}
|
||||
|
||||
template <>
|
||||
void copy<float>(const float* input, float* output, unsigned size) noexcept
|
||||
{
|
||||
// The sentinel is the input here
|
||||
const auto sentinel = input + size;
|
||||
|
||||
if (getSIMDOpStatus(SIMDOps::copy)) {
|
||||
#if SFIZZ_CPU_FAMILY_X86_64 || SFIZZ_CPU_FAMILY_I386
|
||||
if (cpuInfo.has_sse()) {
|
||||
const auto* lastAligned = prevAligned(sentinel);
|
||||
|
||||
while (unaligned(input, output) && input < lastAligned)
|
||||
*output++ = *input++;
|
||||
|
||||
while (input < lastAligned) {
|
||||
_mm_store_ps(output, _mm_load_ps(input));
|
||||
incrementAll<4>(input, output);
|
||||
}
|
||||
// fallthrough from lastAligned to sentinel
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::copy(input, sentinel, output);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -501,39 +501,29 @@ void subtract(T value, absl::Span<T> output) noexcept
|
|||
subtract<T>(value, output.data(), output.size());
|
||||
}
|
||||
|
||||
namespace _internals {
|
||||
template <class T>
|
||||
void snippetCopy(const T*& input, T*& output)
|
||||
{
|
||||
*output++ = *input++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy a span in another
|
||||
*
|
||||
* The output size will be the minimum of the 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::copy>
|
||||
void copy(absl::Span<const T> input, absl::Span<T> output) noexcept
|
||||
template <class T>
|
||||
void copy(const T* input, T* output, unsigned size) noexcept
|
||||
{
|
||||
CHECK(output.size() >= input.size());
|
||||
if (output.data() == input.data() && output.size() == input.size())
|
||||
return;
|
||||
auto* in = input.begin();
|
||||
auto* out = output.begin();
|
||||
auto* sentinel = out + min(input.size(), output.size());
|
||||
while (out < sentinel)
|
||||
_internals::snippetCopy(in, out);
|
||||
std::copy(input, input + size, output);
|
||||
}
|
||||
|
||||
template <>
|
||||
void copy<float, true>(absl::Span<const float> input, absl::Span<float> output) noexcept;
|
||||
void copy<float>(const float* input, float* output, unsigned size) noexcept;
|
||||
|
||||
template <class T>
|
||||
void copy(absl::Span<const T> input, absl::Span<T> output) noexcept
|
||||
{
|
||||
CHECK_SPAN_SIZES(input, output);
|
||||
copy<T>(input.data(), output.data(), minSpanSize(input, output));
|
||||
}
|
||||
|
||||
namespace _internals {
|
||||
// Number of elements in the table, odd for equal volume at center
|
||||
|
|
|
|||
|
|
@ -16,27 +16,6 @@
|
|||
|
||||
constexpr uintptr_t TypeAlignment = 4;
|
||||
|
||||
template <>
|
||||
void sfz::copy<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::snippetCopy<float>(in, out);
|
||||
|
||||
while (out < lastAligned) {
|
||||
_mm_store_ps(out, _mm_load_ps(in));
|
||||
incrementAll<TypeAlignment>(in, out);
|
||||
}
|
||||
|
||||
while (out < sentinel)
|
||||
_internals::snippetCopy<float>(in, out);
|
||||
}
|
||||
|
||||
template <>
|
||||
void sfz::pan<float, true>(absl::Span<const float> panEnvelope, absl::Span<float> leftBuffer, absl::Span<float> rightBuffer) noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -620,7 +620,8 @@ 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::copy<float, false>(input, absl::MakeSpan(output));
|
||||
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, false);
|
||||
sfz::copy<float>(input, absl::MakeSpan(output));
|
||||
REQUIRE(output == input);
|
||||
}
|
||||
|
||||
|
|
@ -628,7 +629,8 @@ 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::copy<float, true>(input, absl::MakeSpan(output));
|
||||
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, true);
|
||||
sfz::copy<float>(input, absl::MakeSpan(output));
|
||||
REQUIRE(output == input);
|
||||
}
|
||||
|
||||
|
|
@ -641,8 +643,10 @@ TEST_CASE("[Helpers] copy (SIMD vs scalar)")
|
|||
absl::c_fill(outputScalar, 0.0f);
|
||||
absl::c_fill(outputSIMD, 0.0f);
|
||||
|
||||
sfz::copy<float, false>(input, absl::MakeSpan(outputScalar));
|
||||
sfz::copy<float, true>(input, absl::MakeSpan(outputSIMD));
|
||||
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, false);
|
||||
sfz::copy<float>(input, absl::MakeSpan(outputScalar));
|
||||
sfz::setSIMDOpStatus(sfz::SIMDOps::copy, true);
|
||||
sfz::copy<float>(input, absl::MakeSpan(outputSIMD));
|
||||
REQUIRE(approxEqual<float>(outputScalar, outputSIMD));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue