Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 1 addition & 42 deletions benchmarks/bench-all.cpp
Original file line number Diff line number Diff line change
@@ -1,45 +1,4 @@
#include "rand_array.h"
#include "x86simdsort.h"
#include <benchmark/benchmark.h>

#define MY_BENCHMARK_CAPTURE(func, T, test_case_name, ...) \
BENCHMARK_PRIVATE_DECLARE(func) \
= (::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark( \
#func "/" #test_case_name "/" #T, \
[](::benchmark::State &st) { \
func<T>(st, __VA_ARGS__); \
})))

#define BENCH_SORT(func, type) \
MY_BENCHMARK_CAPTURE( \
func, type, smallrandom_128, 128, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrandom_256, 256, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrandom_512, 512, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrandom_1k, 1024, std::string("random")); \
MY_BENCHMARK_CAPTURE(func, type, random_5k, 5000, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_100k, 100000, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_1m, 1000000, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_10m, 10000000, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, sorted_10k, 10000, std::string("sorted")); \
MY_BENCHMARK_CAPTURE( \
func, type, constant_10k, 10000, std::string("constant")); \
MY_BENCHMARK_CAPTURE( \
func, type, reverse_10k, 10000, std::string("reverse"));

#define BENCH_PARTIAL(func, type) \
MY_BENCHMARK_CAPTURE(func, type, k10, 10000, 10); \
MY_BENCHMARK_CAPTURE(func, type, k100, 10000, 100); \
MY_BENCHMARK_CAPTURE(func, type, k1000, 10000, 1000); \
MY_BENCHMARK_CAPTURE(func, type, k5000, 10000, 5000);

#include "bench.h"
#include "bench-argsort.hpp"
#include "bench-partial-qsort.hpp"
#include "bench-qselect.hpp"
Expand Down
29 changes: 29 additions & 0 deletions benchmarks/bench-vqsort.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "bench.h"
#define VQSORT_ONLY_STATIC 1
#include "hwy/contrib/sort/vqsort-inl.h"

template <typename T, class... Args>
static void vqsort(benchmark::State &state, Args &&...args)
{
// Get args
auto args_tuple = std::make_tuple(std::move(args)...);
size_t arrsize = std::get<0>(args_tuple);
std::string arrtype = std::get<1>(args_tuple);
// set up array
std::vector<T> arr = get_array<T>(arrtype, arrsize);
std::vector<T> arr_bkp = arr;
// benchmark
for (auto _ : state) {
hwy::HWY_NAMESPACE::VQSortStatic(arr.data(), arrsize, hwy::SortAscending());
state.PauseTiming();
arr = arr_bkp;
state.ResumeTiming();
}
}

BENCH_SORT(vqsort, uint64_t)
BENCH_SORT(vqsort, int64_t)
BENCH_SORT(vqsort, uint32_t)
BENCH_SORT(vqsort, int32_t)
BENCH_SORT(vqsort, float)
BENCH_SORT(vqsort, double)
56 changes: 56 additions & 0 deletions benchmarks/bench.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "rand_array.h"
#include "x86simdsort.h"
#include <benchmark/benchmark.h>

#define MY_BENCHMARK_CAPTURE(func, T, test_case_name, ...) \
BENCHMARK_PRIVATE_DECLARE(func) \
= (::benchmark::internal::RegisterBenchmarkInternal( \
new ::benchmark::internal::FunctionBenchmark( \
#func "/" #test_case_name "/" #T, \
[](::benchmark::State &st) { \
func<T>(st, __VA_ARGS__); \
})))

#define BENCH_SORT(func, type) \
MY_BENCHMARK_CAPTURE( \
func, type, random_128, 128, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_256, 256, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_512, 512, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_1k, 1024, std::string("random")); \
MY_BENCHMARK_CAPTURE(func, type, random_5k, 5000, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_100k, 100000, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_1m, 1000000, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, random_10m, 10000000, std::string("random")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrange_128, 128, std::string("smallrange")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrange_256, 256, std::string("smallrange")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrange_512, 512, std::string("smallrange")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrange_1k, 1024, std::string("smallrange")); \
MY_BENCHMARK_CAPTURE(func, type, smallrange_5k, 5000, std::string("smallrange")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrange_100k, 100000, std::string("smallrange")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrange_1m, 1000000, std::string("smallrange")); \
MY_BENCHMARK_CAPTURE( \
func, type, smallrange_10m, 10000000, std::string("smallrange")); \
MY_BENCHMARK_CAPTURE( \
func, type, sorted_10k, 10000, std::string("sorted")); \
MY_BENCHMARK_CAPTURE( \
func, type, constant_10k, 10000, std::string("constant")); \
MY_BENCHMARK_CAPTURE( \
func, type, reverse_10k, 10000, std::string("reverse"));

#define BENCH_PARTIAL(func, type) \
MY_BENCHMARK_CAPTURE(func, type, k10, 10000, 10); \
MY_BENCHMARK_CAPTURE(func, type, k100, 10000, 100); \
MY_BENCHMARK_CAPTURE(func, type, k1000, 10000, 1000); \
MY_BENCHMARK_CAPTURE(func, type, k5000, 10000, 5000);
12 changes: 12 additions & 0 deletions benchmarks/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,15 @@ libbench += static_library('bench_qsort',
include_directories : [src, lib, utils],
cpp_args : ['-O3'],
)

if fs.is_file('highway/hwy/contrib/sort/vqsort-inl.h')
hwy = include_directories('highway')
libbench += static_library('bench_vqsort',
files(
'bench-vqsort.cpp',
),
dependencies: gbench_dep,
include_directories : [src, lib, utils, hwy],
cpp_args : ['-O3', '-march=native'],
)
endif
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ project('x86-simd-sort', 'cpp',
version : '4.0.0',
license : 'BSD 3-clause',
default_options : ['cpp_std=c++17'])
fs = import('fs')
cpp = meson.get_compiler('cpp')
src = include_directories('src')
lib = include_directories('lib')
Expand Down
5 changes: 4 additions & 1 deletion run-bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
if args.benchcompare:
baseline = ""
contender = ""
if "qsort" in args.benchcompare:
if "vqsort" in args.benchcompare:
baseline = "vqsort.*" + filterb
contender = "simdsort.*" + filterb
elif "qsort" in args.benchcompare:
baseline = "scalarsort.*" + filterb
contender = "simdsort.*" + filterb
elif "select" in args.benchcompare:
Expand Down
21 changes: 17 additions & 4 deletions utils/rand_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ get_uniform_rand_array_with_uniquevalues(int64_t arrsize,
template <typename T>
static std::vector<T>
get_array(std::string arrtype,
int64_t arrsize,
size_t arrsize,
T min = xss::fp::min<T>(),
T max = xss::fp::max<T>())
{
Expand All @@ -80,7 +80,7 @@ get_array(std::string arrtype,
}
else if (arrtype == "constant") {
T temp = get_uniform_rand_array<T>(1, max, min)[0];
for (auto ii = 0; ii < arrsize; ++ii) {
for (size_t ii = 0; ii < arrsize; ++ii) {
arr.push_back(temp);
}
}
Expand All @@ -90,7 +90,20 @@ get_array(std::string arrtype,
std::reverse(arr.begin(), arr.end());
}
else if (arrtype == "smallrange") {
arr = get_uniform_rand_array<T>(arrsize, 10, 1);
arr = get_uniform_rand_array<T>(arrsize, 20, 1);
}
else if (arrtype == "random_5d") {
size_t temp = std::max((size_t) 1, (size_t) (0.5 * arrsize));
std::vector<T> temparr = get_uniform_rand_array<T>(temp);
for (size_t ii = 0; ii < arrsize; ++ii) {
if (ii < temp) {
arr.push_back(temparr[ii]);
}
else {
arr.push_back((T) 0);
}
}
std::shuffle(arr.begin(), arr.end(), std::default_random_engine(42));
}
else if (arrtype == "max_at_the_end") {
arr = get_uniform_rand_array<T>(arrsize, max, min);
Expand Down Expand Up @@ -126,7 +139,7 @@ get_array(std::string arrtype,
else {
val = std::numeric_limits<T>::max();
}
for (auto ii = 1; ii <= arrsize; ++ii) {
for (size_t ii = 1; ii <= arrsize; ++ii) {
if (rand() % 0x1) {
arr[ii] = val;
}
Expand Down