diff --git a/Makefile b/Makefile index 47cfe929..3af92aad 100644 --- a/Makefile +++ b/Makefile @@ -10,17 +10,21 @@ TESTOBJS := $(filter-out $(TESTDIR)/main.o ,$(TESTOBJS)) CXXFLAGS += -I$(SRCDIR) -I$(UTILS) GTESTCFLAGS = `pkg-config --cflags gtest` GTESTLDFLAGS = `pkg-config --libs gtest` +MARCHFLAG = -march=icelake-client -O3 all : test bench +$(UTILS)/cpuinfo.o : $(UTILS)/cpuinfo.cpp + $(CXX) $(CXXFLAGS) -c $(UTILS)/cpuinfo.cpp -o $(UTILS)/cpuinfo.o + $(TESTDIR)/%.o : $(TESTDIR)/%.cpp $(SRCS) - $(CXX) -march=icelake-client -O3 $(CXXFLAGS) $(GTESTCFLAGS) -c $< -o $@ + $(CXX) $(CXXFLAGS) $(MARCHFLAG) $(GTESTCFLAGS) -c $< -o $@ -test: $(TESTDIR)/main.cpp $(TESTOBJS) $(SRCS) - $(CXX) tests/main.cpp $(TESTOBJS) $(CXXFLAGS) $(GTESTLDFLAGS) -o testexe +test: $(TESTDIR)/main.cpp $(TESTOBJS) $(UTILS)/cpuinfo.o $(SRCS) + $(CXX) tests/main.cpp $(TESTOBJS) $(UTILS)/cpuinfo.o $(MARCHFLAG) $(CXXFLAGS) $(GTESTLDFLAGS) -o testexe -bench: $(BENCHDIR)/main.cpp $(SRCS) - $(CXX) $(BENCHDIR)/main.cpp $(CXXFLAGS) -march=icelake-client -O3 -o benchexe +bench: $(BENCHDIR)/main.cpp $(SRCS) $(UTILS)/cpuinfo.o + $(CXX) $(BENCHDIR)/main.cpp $(CXXFLAGS) $(UTILS)/cpuinfo.o $(MARCHFLAG) -o benchexe clean: - rm -f $(TESTDIR)/*.o testexe benchexe \ No newline at end of file + rm -f $(TESTDIR)/*.o testexe benchexe diff --git a/src/avx512-64bit-keyvaluesort.hpp b/src/avx512-64bit-keyvaluesort.hpp index 8140be97..8ed66e14 100644 --- a/src/avx512-64bit-keyvaluesort.hpp +++ b/src/avx512-64bit-keyvaluesort.hpp @@ -803,11 +803,6 @@ void heap_sort(type_t *keys, uint64_t *indexes, int64_t size) } } -template -struct sortkv_t { - T key; - uint64_t value; -}; template void qsort_64bit_(type_t *keys, uint64_t *indexes, diff --git a/tests/main.cpp b/tests/main.cpp index dd5316ce..42ee7088 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -3,6 +3,10 @@ * * SPDX-License-Identifier: BSD-3-Clause * *******************************************/ +#include "avx512-16bit-qsort.hpp" +#include "avx512-32bit-qsort.hpp" +#include "avx512-64bit-keyvaluesort.hpp" +#include "avx512-64bit-qsort.hpp" #include int main(int argc, char **argv) diff --git a/tests/test_all.cpp b/tests/test_keyvalue.cpp similarity index 52% rename from tests/test_all.cpp rename to tests/test_keyvalue.cpp index ff65fff0..95555d7e 100644 --- a/tests/test_all.cpp +++ b/tests/test_keyvalue.cpp @@ -3,66 +3,17 @@ * * SPDX-License-Identifier: BSD-3-Clause * *******************************************/ -#include "avx512-16bit-qsort.hpp" -#include "avx512-32bit-qsort.hpp" -#include "avx512-64bit-keyvaluesort.hpp" -#include "avx512-64bit-qsort.hpp" -#include "cpuinfo.h" +#include "avx512-common-keyvaluesort.h" #include "rand_array.h" #include #include -template -class avx512_sort : public ::testing::Test { -}; -TYPED_TEST_SUITE_P(avx512_sort); - -TYPED_TEST_P(avx512_sort, test_arrsizes) -{ - if (cpu_has_avx512bw()) { - if ((sizeof(TypeParam) == 2) && (!cpu_has_avx512_vbmi2())) { - GTEST_SKIP() << "Skipping this test, it requires avx512_vbmi2"; - } - std::vector arrsizes; - for (int64_t ii = 0; ii < 1024; ++ii) { - arrsizes.push_back((TypeParam)ii); - } - std::vector arr; - std::vector sortedarr; - for (size_t ii = 0; ii < arrsizes.size(); ++ii) { - /* Random array */ - arr = get_uniform_rand_array(arrsizes[ii]); - sortedarr = arr; - /* Sort with std::sort for comparison */ - std::sort(sortedarr.begin(), sortedarr.end()); - avx512_qsort(arr.data(), arr.size()); - ASSERT_EQ(sortedarr, arr); - arr.clear(); - sortedarr.clear(); - } - } - else { - GTEST_SKIP() << "Skipping this test, it requires avx512bw"; - } -} - -REGISTER_TYPED_TEST_SUITE_P(avx512_sort, test_arrsizes); - -using Types = testing::Types; -INSTANTIATE_TYPED_TEST_SUITE_P(TestPrefix, avx512_sort, Types); - template struct sorted_t { K key; K value; }; + template bool compare(sorted_t a, sorted_t b) { @@ -87,7 +38,8 @@ TYPED_TEST_P(TestKeyValueSort, KeyValueSort) for (size_t ii = 0; ii < keysizes.size(); ++ii) { /* Random array */ - keys = get_uniform_rand_array_key(keysizes[ii]); + keys = + get_uniform_rand_array_with_uniquevalues(keysizes[ii]); values = get_uniform_rand_array(keysizes[ii]); for (size_t i = 0; i < keys.size(); i++) { sorted_t tmp_s; @@ -113,4 +65,4 @@ TYPED_TEST_P(TestKeyValueSort, KeyValueSort) REGISTER_TYPED_TEST_SUITE_P(TestKeyValueSort, KeyValueSort); using TypesKv = testing::Types; -INSTANTIATE_TYPED_TEST_SUITE_P(TestPrefixKv, TestKeyValueSort, TypesKv); \ No newline at end of file +INSTANTIATE_TYPED_TEST_SUITE_P(TestPrefixKv, TestKeyValueSort, TypesKv); diff --git a/tests/test_qsort.cpp b/tests/test_qsort.cpp new file mode 100644 index 00000000..ef3aea4f --- /dev/null +++ b/tests/test_qsort.cpp @@ -0,0 +1,56 @@ +/******************************************* + * * Copyright (C) 2022 Intel Corporation + * * SPDX-License-Identifier: BSD-3-Clause + * *******************************************/ + +#include "avx512-common-qsort.h" +#include "cpuinfo.h" +#include "rand_array.h" +#include +#include + +template +class avx512_sort : public ::testing::Test { +}; +TYPED_TEST_SUITE_P(avx512_sort); + +TYPED_TEST_P(avx512_sort, test_arrsizes) +{ + if (cpu_has_avx512bw()) { + if ((sizeof(TypeParam) == 2) && (!cpu_has_avx512_vbmi2())) { + GTEST_SKIP() << "Skipping this test, it requires avx512_vbmi2"; + } + std::vector arrsizes; + for (int64_t ii = 0; ii < 1024; ++ii) { + arrsizes.push_back((TypeParam)ii); + } + std::vector arr; + std::vector sortedarr; + for (size_t ii = 0; ii < arrsizes.size(); ++ii) { + /* Random array */ + arr = get_uniform_rand_array(arrsizes[ii]); + sortedarr = arr; + /* Sort with std::sort for comparison */ + std::sort(sortedarr.begin(), sortedarr.end()); + avx512_qsort(arr.data(), arr.size()); + ASSERT_EQ(sortedarr, arr); + arr.clear(); + sortedarr.clear(); + } + } + else { + GTEST_SKIP() << "Skipping this test, it requires avx512bw"; + } +} + +REGISTER_TYPED_TEST_SUITE_P(avx512_sort, test_arrsizes); + +using Types = testing::Types; +INSTANTIATE_TYPED_TEST_SUITE_P(TestPrefix, avx512_sort, Types); diff --git a/utils/cpuinfo.cpp b/utils/cpuinfo.cpp new file mode 100644 index 00000000..722b82c4 --- /dev/null +++ b/utils/cpuinfo.cpp @@ -0,0 +1,43 @@ +/******************************************* + * * Copyright (C) 2022 Intel Corporation + * * SPDX-License-Identifier: BSD-3-Clause + * *******************************************/ + +#include "cpuinfo.h" + +static void +cpuid(uint32_t feature, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) +{ + __asm__ volatile( + "cpuid" + "\n\t" + : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) + : "a"(feature), "c"(0)); +} + +int cpu_has_avx512_vbmi2() +{ + uint32_t eax(0), ebx(0), ecx(0), edx(0); + cpuid(0x07, &eax, &ebx, &ecx, &edx); + return (ecx >> 6) & 0x1; +} + +int cpu_has_avx512bw() +{ + uint32_t eax(0), ebx(0), ecx(0), edx(0); + cpuid(0x07, &eax, &ebx, &ecx, &edx); + return (ebx >> 30) & 0x1; +} + +// TODO: +//int check_os_supports_avx512() +//{ +// uint32_t eax(0), ebx(0), ecx(0), edx(0); +// cpuid(0x01, &eax, &ebx, &ecx, &edx); +// // XSAVE: +// if ((ecx >> 27) & 0x1) { +// uint32_t xget_eax, xget_edx, index(0); +// __asm__ ("xgetbv" : "=a"(xget_eax), "=d"(xget_edx) : "c" (index)) +// } +// +//} diff --git a/utils/cpuinfo.h b/utils/cpuinfo.h index 6ed5cc96..1049a343 100644 --- a/utils/cpuinfo.h +++ b/utils/cpuinfo.h @@ -3,41 +3,9 @@ * * SPDX-License-Identifier: BSD-3-Clause * *******************************************/ +#include #include -static void -cpuid(uint32_t feature, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) -{ - __asm__ volatile( - "cpuid" - "\n\t" - : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) - : "a"(feature), "c"(0)); -} +int cpu_has_avx512_vbmi2(); -int cpu_has_avx512_vbmi2() -{ - uint32_t eax(0), ebx(0), ecx(0), edx(0); - cpuid(0x07, &eax, &ebx, &ecx, &edx); - return (ecx >> 6) & 0x1; -} - -int cpu_has_avx512bw() -{ - uint32_t eax(0), ebx(0), ecx(0), edx(0); - cpuid(0x07, &eax, &ebx, &ecx, &edx); - return (ebx >> 30) & 0x1; -} - -// TODO: -//int check_os_supports_avx512() -//{ -// uint32_t eax(0), ebx(0), ecx(0), edx(0); -// cpuid(0x01, &eax, &ebx, &ecx, &edx); -// // XSAVE: -// if ((ecx >> 27) & 0x1) { -// uint32_t xget_eax, xget_edx, index(0); -// __asm__ ("xgetbv" : "=a"(xget_eax), "=d"(xget_edx) : "c" (index)) -// } -// -//} +int cpu_has_avx512bw(); diff --git a/utils/rand_array.h b/utils/rand_array.h index 804226f7..01163582 100644 --- a/utils/rand_array.h +++ b/utils/rand_array.h @@ -41,52 +41,16 @@ static std::vector get_uniform_rand_array( } return arr; } -template -static std::vector get_uniform_rand_array_key( - int64_t arrsize, - T max = std::numeric_limits::max(), - T min = std::numeric_limits::min(), - typename std::enable_if::value>::type * = 0) -{ - std::vector arr; - std::random_device r; - std::default_random_engine e1(r()); - std::uniform_int_distribution uniform_dist(min, max); - for (int64_t ii = 0; ii < arrsize; ++ii) { - - while (true) { - T tmp = uniform_dist(e1); - auto iter = std::find(arr.begin(), arr.end(), tmp); - if (iter == arr.end()) { - arr.emplace_back(tmp); - break; - } - } - } - return arr; -} template -static std::vector get_uniform_rand_array_key( +static std::vector get_uniform_rand_array_with_uniquevalues( int64_t arrsize, T max = std::numeric_limits::max(), - T min = std::numeric_limits::min(), - typename std::enable_if::value>::type * = 0) + T min = std::numeric_limits::min()) { - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_real_distribution dis(min, max); - std::vector arr; - for (int64_t ii = 0; ii < arrsize; ++ii) { - - while (true) { - T tmp = dis(gen); - auto iter = std::find(arr.begin(), arr.end(), tmp); - if (iter == arr.end()) { - arr.emplace_back(tmp); - break; - } - } - } + std::vector arr = get_uniform_rand_array(arrsize, max, min); + typename std::vector::iterator ip = + std::unique(arr.begin(), arr.begin() + arrsize); + arr.resize(std::distance(arr.begin(), ip)); return arr; -} \ No newline at end of file +}