Corrected a stack overflow and added benchmarks for the interleaved read
This commit is contained in:
parent
c014a34385
commit
748186efdf
5 changed files with 60 additions and 28 deletions
|
|
@ -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)
|
||||
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)
|
||||
|
|
@ -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<float> buffer (size);
|
||||
std::array<float, 2*size> 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<float> buffer (size);
|
||||
std::array<float, 2*size> input;
|
||||
std::iota(input.begin(), input.end(), 1.0f);
|
||||
for (auto _ : state) {
|
||||
buffer.readInterleaved<VectorOperations::sse>(input.data(), size);
|
||||
}
|
||||
}
|
||||
BENCHMARK(Interleaved_Read_SSE);
|
||||
BENCHMARK_MAIN();
|
||||
35
benchmarks/AudioBuffer_Interleaved_Read.cpp
Normal file
35
benchmarks/AudioBuffer_Interleaved_Read.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#include <benchmark/benchmark.h>
|
||||
#include "../sources/AudioBuffer.h"
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
static void Interleaved_Read(benchmark::State& state) {
|
||||
AudioBuffer<float> buffer (state.range(0));
|
||||
std::vector<float> 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<float> buffer (state.range(0));
|
||||
std::vector<float> input (state.range(0) * 2);
|
||||
std::iota(input.begin(), input.end(), 1.0f);
|
||||
for (auto _ : state) {
|
||||
buffer.readInterleaved<VectorOperations::sse>(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<float> buffer (state.range(0));
|
||||
std::vector<float> input (state.range(0) * 2);
|
||||
std::iota(input.begin(), input.end(), 1.0f);
|
||||
for (auto _ : state) {
|
||||
buffer.readInterleaved<VectorOperations::sse>(input.data() + 1, state.range(0) - 1);
|
||||
}
|
||||
}
|
||||
BENCHMARK(Unaligned_Interleaved_Read_SSE)->Range((8<<10) + 3, (8<<20) + 3);
|
||||
BENCHMARK_MAIN();
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include "Helpers.h"
|
||||
#include "Globals.h"
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
|
||||
template<class Type, unsigned int NumChannels = sfz::config::numChannels, unsigned int Alignment = config::defaultAlignment>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<float> buffer (size);
|
||||
std::vector<float> input (2*size);
|
||||
std::iota(input.begin(), input.end(), 1.0f);
|
||||
buffer.readInterleaved(input.data(), size);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue