From 748186efdf63b551680c0889e2ff4fb1875b08ef Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 1 Aug 2019 01:03:05 +0200 Subject: [PATCH] Corrected a stack overflow and added benchmarks for the interleaved read --- CMakeLists.txt | 16 ++++++--- ...{AudioBuffers.cpp => AudioBuffer_Fill.cpp} | 21 ----------- benchmarks/AudioBuffer_Interleaved_Read.cpp | 35 +++++++++++++++++++ sources/AudioBuffer.h | 7 ++-- tests/AudioBuffer.cpp | 9 +++++ 5 files changed, 60 insertions(+), 28 deletions(-) rename benchmarks/{AudioBuffers.cpp => AudioBuffer_Fill.cpp} (72%) create mode 100644 benchmarks/AudioBuffer_Interleaved_Read.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9400fcad..11d29a77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.13) # You need to generate the AppConfig.h and the JuceHeader.h through the Projucer; the rest is more or less here project(sfizz VERSION 1.0.0 LANGUAGES CXX) @@ -76,9 +76,17 @@ target_include_directories(sfizz_tests SYSTEM PRIVATE sources) file(COPY "tests" DESTINATION ${CMAKE_BINARY_DIR}) ############################### -add_executable(bench_audiobuffers benchmarks/AudioBuffers.cpp ${COMMON_SOURCES}) +add_executable(bench_ab_fill benchmarks/AudioBuffer_Fill.cpp ${COMMON_SOURCES}) # Per OS properties if(UNIX) - target_link_libraries(bench_audiobuffers stdc++fs) + target_link_libraries(bench_ab_fill stdc++fs) endif(UNIX) -target_link_libraries(bench_audiobuffers absl::strings benchmark) \ No newline at end of file +target_link_libraries(bench_ab_fill absl::strings benchmark) + +############################### +add_executable(bench_ab_read benchmarks/AudioBuffer_Interleaved_Read.cpp ${COMMON_SOURCES}) +# Per OS properties +if(UNIX) + target_link_libraries(bench_ab_read stdc++fs) +endif(UNIX) +target_link_libraries(bench_ab_read absl::strings benchmark) \ No newline at end of file diff --git a/benchmarks/AudioBuffers.cpp b/benchmarks/AudioBuffer_Fill.cpp similarity index 72% rename from benchmarks/AudioBuffers.cpp rename to benchmarks/AudioBuffer_Fill.cpp index bd3a766b..752a47f2 100644 --- a/benchmarks/AudioBuffers.cpp +++ b/benchmarks/AudioBuffer_Fill.cpp @@ -68,25 +68,4 @@ static void Split_Fill_double(benchmark::State& state) { } BENCHMARK(Split_Fill_double); - -constexpr int size { 1039247 }; -static void Interleaved_Read(benchmark::State& state) { - AudioBuffer buffer (size); - std::array input; - std::iota(input.begin(), input.end(), 1.0f); - for (auto _ : state) { - buffer.readInterleaved(input.data(), size); - } -} -BENCHMARK(Interleaved_Read); - -static void Interleaved_Read_SSE(benchmark::State& state) { - AudioBuffer buffer (size); - std::array input; - std::iota(input.begin(), input.end(), 1.0f); - for (auto _ : state) { - buffer.readInterleaved(input.data(), size); - } -} -BENCHMARK(Interleaved_Read_SSE); BENCHMARK_MAIN(); \ No newline at end of file diff --git a/benchmarks/AudioBuffer_Interleaved_Read.cpp b/benchmarks/AudioBuffer_Interleaved_Read.cpp new file mode 100644 index 00000000..ee7cdafc --- /dev/null +++ b/benchmarks/AudioBuffer_Interleaved_Read.cpp @@ -0,0 +1,35 @@ +#include +#include "../sources/AudioBuffer.h" +#include +#include + +static void Interleaved_Read(benchmark::State& state) { + AudioBuffer buffer (state.range(0)); + std::vector input (state.range(0) * 2); + std::iota(input.begin(), input.end(), 1.0f); + for (auto _ : state) { + buffer.readInterleaved(input.data(), state.range(0)); + } +} +BENCHMARK(Interleaved_Read)->Range((8<<10) + 3, (8<<20) + 3); + +static void Interleaved_Read_SSE(benchmark::State& state) { + AudioBuffer buffer (state.range(0)); + std::vector input (state.range(0) * 2); + std::iota(input.begin(), input.end(), 1.0f); + for (auto _ : state) { + buffer.readInterleaved(input.data(), state.range(0)); + } +} +BENCHMARK(Interleaved_Read_SSE)->Range((8<<10) + 3, (8<<20) + 3); + +static void Unaligned_Interleaved_Read_SSE(benchmark::State& state) { + AudioBuffer buffer (state.range(0)); + std::vector input (state.range(0) * 2); + std::iota(input.begin(), input.end(), 1.0f); + for (auto _ : state) { + buffer.readInterleaved(input.data() + 1, state.range(0) - 1); + } +} +BENCHMARK(Unaligned_Interleaved_Read_SSE)->Range((8<<10) + 3, (8<<20) + 3); +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/sources/AudioBuffer.h b/sources/AudioBuffer.h index 373d36f9..fcb9fba3 100644 --- a/sources/AudioBuffer.h +++ b/sources/AudioBuffer.h @@ -3,6 +3,7 @@ #include "Helpers.h" #include "Globals.h" #include +#include #include template @@ -13,6 +14,7 @@ public: AudioBuffer() = default; AudioBuffer(int numFrames) { + DBG("Building an audiobuffer of size " << numFrames); resize(numFrames); } @@ -73,9 +75,9 @@ public: const float* end = input + 2 * lastAligned; while (in < end) { - auto input0 = _mm_load_ps(in); + auto input0 = _mm_loadu_ps(in); in += 4; - auto input1 = _mm_load_ps(in); + auto input1 = _mm_loadu_ps(in); in += 4; auto intermediate0 = _mm_unpacklo_ps(input0, input1); auto intermediate1 = _mm_unpackhi_ps(input0, input1); @@ -86,7 +88,6 @@ public: out0 += 4; out1 += 4; } - for (auto chanIdx = 0; chanIdx < NumChannels; chanIdx++) { auto* _in = input + 2 * lastAligned + chanIdx; diff --git a/tests/AudioBuffer.cpp b/tests/AudioBuffer.cpp index 708e99bb..34b310da 100644 --- a/tests/AudioBuffer.cpp +++ b/tests/AudioBuffer.cpp @@ -512,4 +512,13 @@ TEST_CASE("[AudioBuffer] Interleave read unaligned end -- SSE") for (auto frameIdx = 0; frameIdx < buffer.getNumFrames(); ++frameIdx) real[realIdx++] = buffer(chanIdx, frameIdx); REQUIRE( real == expected ); +} + +TEST_CASE("[AudioBuffer] Fill a big Audiobuffer") +{ + constexpr int size { 2039247 }; + AudioBuffer buffer (size); + std::vector input (2*size); + std::iota(input.begin(), input.end(), 1.0f); + buffer.readInterleaved(input.data(), size); } \ No newline at end of file