Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ jobs:
- { compiler: 'gcc', version: '13', flags: 'enable_xtl_complex' }
- { compiler: 'gcc', version: '14', flags: 'avx' }
- { compiler: 'gcc', version: '13', flags: 'avx512' }
- { compiler: 'gcc', version: '12', flags: 'i386' }
- { compiler: 'gcc', version: '13', flags: 'avx512pf' }
- { compiler: 'gcc', version: '13', flags: 'avx512vbmi' }
- { compiler: 'gcc', version: '14', flags: 'avx512vbmi2' }
Expand All @@ -34,10 +33,6 @@ jobs:
GCC_VERSION=${{ matrix.sys.version }}
sudo apt-get update
sudo apt-get --no-install-suggests --no-install-recommends install g++-$GCC_VERSION
sudo dpkg --add-architecture i386
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get --no-install-suggests --no-install-recommends install gcc-$GCC_VERSION-multilib g++-$GCC_VERSION-multilib linux-libc-dev:i386
CC=gcc-$GCC_VERSION
echo "CC=$CC" >> $GITHUB_ENV
CXX=g++-$GCC_VERSION
Expand Down Expand Up @@ -95,9 +90,6 @@ jobs:
if [[ '${{ matrix.sys.flags }}' == 'avx512vnni' ]]; then
CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS -DTARGET_ARCH=knm"
fi
if [[ '${{ matrix.sys.flags }}' == 'i386' ]]; then
CXX_FLAGS="$CXX_FLAGS -m32"
fi
if [[ '${{ matrix.sys.flags }}' == 'force_no_instr_set' ]]; then
:
else
Expand Down
11 changes: 7 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ endif()
# Build
# =====

set(XSIMDALGO_HEADERS
${XSIMDALGO_INCLUDE_DIR}/xsimd_algorithm/algorithms.hpp
)

add_library(xsimd-algorithm INTERFACE)

target_include_directories(xsimd-algorithm INTERFACE
Expand All @@ -37,12 +33,19 @@ target_compile_features(xsimd-algorithm INTERFACE cxx_std_20)
target_link_libraries(xsimd-algorithm INTERFACE xsimd)

OPTION(BUILD_TESTS "xsimd-algorithm test suite" OFF)
OPTION(BUILD_BENCHMARK "xsimd-algorithm benchmark suite" OFF)

add_subdirectory(test-utils)

if(BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif()

if(BUILD_BENCHMARK)
add_subdirectory(benchmark)
endif()

# Installation
# ============

Expand Down
27 changes: 27 additions & 0 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
############################################################################
# Copyright (c) xsimd-algorithm contributors #
# #
# Distributed under the terms of the BSD 3-Clause License. #
# #
# The full license is in the file LICENSE, distributed with this software. #
############################################################################

cmake_minimum_required(VERSION 3.8)

project(xsimd-algorithm-benchmark)

if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
find_package(xsimd-algorithm REQUIRED CONFIG)
endif ()

find_package(benchmark REQUIRED)

set(XSIMD_ALGORITHM_BENCHMARKS
main.cpp
bench_math.cpp
bench_map.cpp
)

add_executable(benchmark_xsimd_algorithm ${XSIMD_ALGORITHM_BENCHMARKS})
target_link_libraries(benchmark_xsimd_algorithm
PRIVATE xsimd-algorithm xsimd::test-utils benchmark::benchmark)
158 changes: 158 additions & 0 deletions benchmark/bench_map.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/****************************************************************************
* Copyright (c) xsimd-algorithm contributors *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#include <cstddef>
#include <cstdint>

#include <benchmark/benchmark.h>

#include "map_binary_utils.hpp"
#include "map_unary_utils.hpp"
#include "xsimd_algorithm/map.hpp"
#include "xsimd_test_utils/map_binary_data.hpp"
#include "xsimd_test_utils/map_unary_data.hpp"
#include "xsimd_test_utils/utils.hpp"

namespace
{
using xsimd::bench::bench_binary_scalar;
using xsimd::bench::bench_map_binary;
using xsimd::bench::bench_map_unary;
using xsimd::bench::bench_scalar;
using xsimd::bench::bench_transform;
using xsimd::bench::register_binary_bench;
using xsimd::bench::register_bench;
using xsimd::alignment_options;
using xsimd::map_options;

template <typename Op>
void register_benches()
{
using input_t = typename Op::input_t;
using arch = xsimd::default_arch;
using aligned_alloc = typename xsimd::test::aligned_vector<input_t, arch>::allocator_type;
using unaligned_alloc = typename xsimd::test::unaligned_vector<input_t, arch>::allocator_type;

constexpr auto noalign = alignment_options {};
constexpr auto noopts = map_options { .unroll_factor = 1, .pure = false };

register_bench<Op, arch>("aligned/scalar", bench_scalar<Op, aligned_alloc>);
register_bench<Op, arch>("aligned/simd/transform", bench_transform<Op, aligned_alloc, arch>);
register_bench<Op, arch>(
"aligned/simd/map",
bench_map_unary<Op, aligned_alloc, arch, noalign, noopts>);
register_bench<Op, arch>(
"aligned/simd/map:pure",
bench_map_unary<
Op, aligned_alloc, arch,
noalign, map_options { .unroll_factor = 1, .pure = true }>);
register_bench<Op, arch>(
"aligned/simd/map:unroll4",
bench_map_unary<
Op, aligned_alloc, arch, noalign, map_options { .unroll_factor = 4 }>);
register_bench<Op, arch>(
"aligned/simd/map:noheader",
bench_map_unary<
Op, aligned_alloc, arch,
alignment_options { .start_aligned = true }, noopts>);
register_bench<Op, arch>(
"aligned/simd/map:noheader+pure+unroll4",
bench_map_unary<
Op, aligned_alloc, arch,
alignment_options { .start_aligned = true }, map_options { .unroll_factor = 4, .pure = true }>);

register_bench<Op, arch>("unaligned/scalar", bench_scalar<Op, unaligned_alloc>);
register_bench<Op, arch>("unaligned/simd/transform", bench_transform<Op, unaligned_alloc, arch>);
register_bench<Op, arch>(
"unaligned/simd/map",
bench_map_unary<Op, unaligned_alloc, arch, noalign, noopts>);
register_bench<Op, arch>(
"unaligned/simd/map:pure",
bench_map_unary<
Op, unaligned_alloc, arch,
noalign, map_options { .unroll_factor = 1, .pure = true }>);
register_bench<Op, arch>(
"unaligned/simd/map:unroll4",
bench_map_unary<
Op, unaligned_alloc, arch, noalign, map_options { .unroll_factor = 4 }>);
register_bench<Op, arch>(
"unaligned/simd/map:pure+unroll4",
bench_map_unary<
Op, unaligned_alloc, arch,
noalign, map_options { .unroll_factor = 4, .pure = true }>);
}

template <typename Op>
void register_binary_benches()
{
using lhs_t = typename Op::lhs_t;
using arch = xsimd::default_arch;
using aligned_alloc = typename xsimd::test::aligned_vector<lhs_t, arch>::allocator_type;
using unaligned_alloc = typename xsimd::test::unaligned_vector<lhs_t, arch>::allocator_type;

constexpr auto noalign = alignment_options {};
constexpr auto noopts = map_options { .unroll_factor = 1, .pure = false };

register_binary_bench<Op, arch>("aligned/scalar", bench_binary_scalar<Op, aligned_alloc>);
register_binary_bench<Op, arch>(
"aligned/simd/map",
bench_map_binary<Op, aligned_alloc, arch, noalign, noopts>);
register_binary_bench<Op, arch>(
"aligned/simd/map:pure",
bench_map_binary<
Op, aligned_alloc, arch,
noalign, map_options { .unroll_factor = 1, .pure = true }>);
register_binary_bench<Op, arch>(
"aligned/simd/map:unroll4",
bench_map_binary<
Op, aligned_alloc, arch, noalign, map_options { .unroll_factor = 4 }>);
register_binary_bench<Op, arch>(
"aligned/simd/map:noheader",
bench_map_binary<
Op, aligned_alloc, arch,
alignment_options { .start_aligned = true }, noopts>);
register_binary_bench<Op, arch>(
"aligned/simd/map:noheader+pure+unroll4",
bench_map_binary<
Op, aligned_alloc, arch,
alignment_options { .start_aligned = true }, map_options { .unroll_factor = 4, .pure = true }>);

register_binary_bench<Op, arch>("unaligned/scalar", bench_binary_scalar<Op, unaligned_alloc>);
register_binary_bench<Op, arch>(
"unaligned/simd/map",
bench_map_binary<Op, unaligned_alloc, arch, noalign, noopts>);
register_binary_bench<Op, arch>(
"unaligned/simd/map:pure",
bench_map_binary<
Op, unaligned_alloc, arch,
noalign, map_options { .unroll_factor = 1, .pure = true }>);
register_binary_bench<Op, arch>(
"unaligned/simd/map:unroll4",
bench_map_binary<
Op, unaligned_alloc, arch, noalign, map_options { .unroll_factor = 4 }>);
register_binary_bench<Op, arch>(
"unaligned/simd/map:pure+unroll4",
bench_map_binary<
Op, unaligned_alloc, arch,
noalign, map_options { .unroll_factor = 4, .pure = true }>);
}

bool const registered = []
{
register_benches<xsimd::test::sqrt_op<float>>();
register_benches<xsimd::test::sqrt_op<double>>();
register_benches<xsimd::test::abs_op<float>>();
register_benches<xsimd::test::abs_op<double>>();
register_benches<xsimd::test::exp_op<float>>();
register_benches<xsimd::test::exp_op<double>>();
register_binary_benches<xsimd::test::add_op<std::int32_t>>();
register_binary_benches<xsimd::test::multiply_op<float>>();
register_binary_benches<xsimd::test::mixed_multiply_op>();
return true;
}();
}
84 changes: 84 additions & 0 deletions benchmark/bench_math.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/****************************************************************************
* Copyright (c) xsimd-algorithm contributors *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#include <cstddef>

#include <benchmark/benchmark.h>

#include "map_binary_utils.hpp"
#include "map_unary_utils.hpp"
#include "xsimd_test_utils/map_binary_data.hpp"
#include "xsimd_test_utils/map_unary_data.hpp"
#include "xsimd_test_utils/utils.hpp"

namespace
{
using xsimd::bench::bench_binary_scalar;
using xsimd::bench::bench_map_binary;
using xsimd::bench::bench_map_unary;
using xsimd::bench::bench_scalar;
using xsimd::bench::register_binary_bench;
using xsimd::bench::register_bench;
using xsimd::alignment_options;

/// Register math benchmarks.
///
/// To avoid an explosion of benchmarks, we only add a simple aligned benchmark.
/// This will let us know the performance of the xsimd wrappers.
/// See bench_map for benchmarks on the different flavor of mapping, alignment,
/// headers and trailers.
///
/// This benchmark aims to test raw the performance of intrinsic, unrelated to
/// how they are iterated on (alignment, memory etc). To do so, they aim to stay
/// in L1 cache.
template <typename Op>
void register_benches()
{
using input_t = typename Op::input_t;
using arch = xsimd::default_arch;
using aligned_alloc = typename xsimd::test::aligned_vector<input_t, arch>::allocator_type;

register_bench<Op, arch>(
"hot/scalar", bench_scalar<Op, aligned_alloc>, /* sizes = */ { 1024 });
register_bench<Op, arch>(
"hot/simd",
bench_map_unary<Op, aligned_alloc, arch, alignment_options { .start_aligned = true, .end_aligned = true }>,
/* sizes = */ { 1024 });
}

template <typename Op>
void register_binary_benches()
{
using lhs_t = typename Op::lhs_t;
using arch = xsimd::default_arch;
using aligned_alloc = typename xsimd::test::aligned_vector<lhs_t, arch>::allocator_type;

register_binary_bench<Op, arch>(
"hot/scalar", bench_binary_scalar<Op, aligned_alloc>, /* sizes = */ { 1024 });
register_binary_bench<Op, arch>(
"hot/simd",
bench_map_binary<Op, aligned_alloc, arch, alignment_options { .start_aligned = true, .end_aligned = true }>,
/* sizes = */ { 1024 });
}

bool const registered = []
{
register_benches<xsimd::test::sqrt_op<float>>();
register_benches<xsimd::test::sqrt_op<double>>();
register_benches<xsimd::test::abs_op<float>>();
register_benches<xsimd::test::abs_op<double>>();
register_benches<xsimd::test::exp_op<float>>();
register_benches<xsimd::test::exp_op<double>>();
register_benches<xsimd::test::widen_op<std::int8_t>>();
register_benches<xsimd::test::widen_op<std::int16_t>>();
register_benches<xsimd::test::widen_op<std::int32_t>>();
register_binary_benches<xsimd::test::add_op<std::int32_t>>();
register_binary_benches<xsimd::test::multiply_op<float>>();
return true;
}();
}
Loading
Loading