Add xorshift-rand from lemire for comparing performance

This commit is contained in:
Dmitrii Kovalkov 2020-04-14 17:48:33 +02:00
parent 9674482a6c
commit 808bb14c5c
9 changed files with 144 additions and 2 deletions

View File

@ -27,6 +27,7 @@ add_subdirectory (murmurhash)
add_subdirectory (replxx-cmake)
add_subdirectory (ryu-cmake)
add_subdirectory (unixodbc-cmake)
add_subdirectory (SIMDxorshift-cmake)
add_subdirectory (poco-cmake)

View File

@ -0,0 +1,12 @@
set(SIMDXORSHIFT_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/SIMDxorshift/include")
set(SIMDXORSHIFT_SRC_DIR "${SIMDXORSHIFT_INCLUDE_DIR}/../src")
set(SIMDXORSHIFT_SRC
${SIMDXORSHIFT_SRC_DIR}/xorshift128plus.c
${SIMDXORSHIFT_SRC_DIR}/simdxorshift128plus.c
)
set(SIMDXORSHIFT_LIBRARY "simdxorshift")
add_library(${SIMDXORSHIFT_LIBRARY} ${SIMDXORSHIFT_SRC})
target_include_directories(${SIMDXORSHIFT_LIBRARY} PUBLIC "${SIMDXORSHIFT_INCLUDE_DIR}")
target_compile_options(${SIMDXORSHIFT_LIBRARY} PRIVATE -mavx2)

View File

@ -83,6 +83,10 @@ if(USE_RAPIDJSON)
target_include_directories(clickhouse_functions SYSTEM PRIVATE ${RAPIDJSON_INCLUDE_DIR})
endif()
target_link_libraries(clickhouse_functions PUBLIC "simdxorshift")
message(STATUS "Using SIMDXORSHIFT ${SIMDXORSHIFT_LIBRARY}")
add_subdirectory(GatherUtils)
target_link_libraries(clickhouse_functions PRIVATE clickhouse_functions_gatherutils)

View File

@ -4,7 +4,6 @@
#include <Common/randomSeed.h>
#include <common/unaligned.h>
namespace DB
{

View File

@ -44,7 +44,6 @@ struct RandImpl
static void execute(char * output, size_t size);
};
template <typename ToType, typename Name>
class FunctionRandom : public IFunction
{

View File

@ -0,0 +1,40 @@
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionsRandom.h>
#include <Common/HashTable/Hash.h>
#include <Common/randomSeed.h>
#include <common/unaligned.h>
#include <Functions/FunctionFactory.h>
#include <Functions/SIMDxorshift.h>
extern "C" {
#include <simdxorshift128plus.h>
}
namespace DB
{
BEGIN_AVX_SPECIFIC_CODE
void RandImplXorshift::execute(char * output, size_t size)
{
avx_xorshift128plus_key_t mykey;
avx_xorshift128plus_init(324, 4444, &mykey);
// TODO(set last 16 bytes)
for (auto * end = output + size - 16; output < end; output += 32) {
unalignedStore<__m256i>(output, avx_xorshift128plus(&mykey));
}
}
struct NameRandXorshift { static constexpr auto name = "randxorshift"; };
using FunctionRandXorshift = FunctionRandomXorshift<UInt32, NameRandXorshift>;
void registerFunctionRandXorshift(FunctionFactory & factory)
{
factory.registerFunction<FunctionRandXorshift>();
}
END_TARGET_SPECIFIC_CODE
}

View File

@ -0,0 +1,84 @@
#pragma once
#include <DataTypes/DataTypesNumber.h>
#include <Columns/ColumnVector.h>
#include <Functions/IFunctionImpl.h>
#include <IO/WriteHelpers.h>
#include <Functions/TargetSpecific.h>
#include <Functions/PerformanceAdaptors.h>
namespace DB
{
namespace ErrorCodes
{
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
}
struct RandImplXorshift
{
static void execute(char * output, size_t size);
};
template <typename ToType, typename Name>
class FunctionRandomXorshift : public IFunction
{
public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context &) {
return std::make_shared<FunctionRandomXorshift<ToType, Name>>();
}
String getName() const override
{
return name;
}
bool isDeterministic() const override { return false; }
bool isDeterministicInScopeOfQuery() const override { return false; }
bool useDefaultImplementationForNulls() const override { return false; }
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() > 1)
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
+ toString(arguments.size()) + ", should be 0 or 1.",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
return std::make_shared<DataTypeNumber<ToType>>();
}
void executeImpl(Block & block, const ColumnNumbers &, size_t result, size_t input_rows_count) override
{
auto col_to = ColumnVector<ToType>::create();
typename ColumnVector<ToType>::Container & vec_to = col_to->getData();
size_t size = input_rows_count;
vec_to.resize(size);
RandImplXorshift::execute(reinterpret_cast<char *>(vec_to.data()), vec_to.size() * sizeof(ToType));
block.getByPosition(result).column = std::move(col_to);
}
};
// template <typename ToType, typename Name>
// class FunctionRandom : public FunctionPerformanceAdaptor<TargetSpecific::Default::FunctionRandom<ToType, Name>>
// {
// public:
// FunctionRandom() {
// registerImplementation<TargetSpecific::SSE4::FunctionRandom<ToType, Name>>(TargetArch::SSE4);
// registerImplementation<TargetSpecific::AVX::FunctionRandom<ToType, Name>>(TargetArch::AVX);
// registerImplementation<TargetSpecific::AVX2::FunctionRandom<ToType, Name>>(TargetArch::AVX2);
// registerImplementation<TargetSpecific::AVX512::FunctionRandom<ToType, Name>>(TargetArch::AVX512);
// }
// static FunctionPtr create(const Context &) {
// return std::make_shared<FunctionRandom<ToType, Name>>();
// }
// };
}

View File

@ -10,6 +10,7 @@ void registerFunctionRandomPrintableASCII(FunctionFactory & factory);
void registerFunctionRandomString(FunctionFactory & factory);
void registerFunctionRandomFixedString(FunctionFactory & factory);
void registerFunctionRandomStringUTF8(FunctionFactory & factory);
void registerFunctionRandXorshift(FunctionFactory & factory);
void registerFunctionsRandom(FunctionFactory & factory)
{
@ -21,6 +22,7 @@ void registerFunctionsRandom(FunctionFactory & factory)
registerFunctionRandomString(factory);
registerFunctionRandomFixedString(factory);
registerFunctionRandomStringUTF8(factory);
registerFunctionRandXorshift(factory);
}
}

View File

@ -20,4 +20,5 @@
<query>SELECT rand() FROM {table} </query>
<query>SELECT rand64() FROM {table} </query>
<query>SELECT randxorshift() FROM {table} </query>
</test>