mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-29 11:02:08 +00:00
dbms: Server: performance optimizations. [#METR-15210]
This commit is contained in:
parent
793d1accfc
commit
1143cfb7ad
@ -226,7 +226,6 @@ template<bool compute_marginal_moments>
|
|||||||
class BaseCovarianceData
|
class BaseCovarianceData
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual ~BaseCovarianceData() = default;
|
|
||||||
void incrementMarginalMoments(Float64 left_incr, Float64 right_incr) {}
|
void incrementMarginalMoments(Float64 left_incr, Float64 right_incr) {}
|
||||||
void mergeWith(const BaseCovarianceData & source) {}
|
void mergeWith(const BaseCovarianceData & source) {}
|
||||||
void serialize(WriteBuffer & buf) const {}
|
void serialize(WriteBuffer & buf) const {}
|
||||||
@ -237,8 +236,6 @@ template<>
|
|||||||
class BaseCovarianceData<true>
|
class BaseCovarianceData<true>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
virtual ~BaseCovarianceData() = default;
|
|
||||||
|
|
||||||
void incrementMarginalMoments(Float64 left_incr, Float64 right_incr)
|
void incrementMarginalMoments(Float64 left_incr, Float64 right_incr)
|
||||||
{
|
{
|
||||||
left_m2 += left_incr;
|
left_m2 += left_incr;
|
||||||
|
@ -94,24 +94,34 @@ namespace DB
|
|||||||
|
|
||||||
/// Реализация функций округления на низком уровне.
|
/// Реализация функций округления на низком уровне.
|
||||||
|
|
||||||
template<typename T, int rounding_mode>
|
template<typename T, int rounding_mode, bool with_scale>
|
||||||
struct RoundingComputation
|
struct RoundingComputation
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int rounding_mode>
|
template<int rounding_mode, bool with_scale>
|
||||||
struct RoundingComputation<Float32, rounding_mode>
|
struct RoundingComputation<Float32, rounding_mode, with_scale>
|
||||||
{
|
{
|
||||||
using Data = std::array<Float32, 4>;
|
using Data = std::array<Float32, 4>;
|
||||||
using Scale = __m128;
|
using Scale = __m128;
|
||||||
|
|
||||||
static inline void prepareScale(size_t scale, Scale & mm_scale)
|
template<bool with_scale2 = with_scale>
|
||||||
|
static inline void prepareScale(size_t scale, Scale & mm_scale,
|
||||||
|
typename std::enable_if<with_scale2>::type * = nullptr)
|
||||||
{
|
{
|
||||||
Float32 fscale = static_cast<Float32>(scale);
|
Float32 fscale = static_cast<Float32>(scale);
|
||||||
mm_scale = _mm_load1_ps(&fscale);
|
mm_scale = _mm_load1_ps(&fscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void compute(const Data & in, const Scale & mm_scale, Data & out)
|
template<bool with_scale2 = with_scale>
|
||||||
|
static inline void prepareScale(size_t scale, Scale & mm_scale,
|
||||||
|
typename std::enable_if<!with_scale2>::type * = nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool with_scale2 = with_scale>
|
||||||
|
static inline void compute(const Data & in, const Scale & mm_scale, Data & out,
|
||||||
|
typename std::enable_if<with_scale2>::type * = nullptr)
|
||||||
{
|
{
|
||||||
__m128 mm_value = _mm_loadu_ps(reinterpret_cast<const Float32 *>(&in));
|
__m128 mm_value = _mm_loadu_ps(reinterpret_cast<const Float32 *>(&in));
|
||||||
mm_value = _mm_mul_ps(mm_value, mm_scale);
|
mm_value = _mm_mul_ps(mm_value, mm_scale);
|
||||||
@ -119,21 +129,40 @@ namespace DB
|
|||||||
mm_value = _mm_div_ps(mm_value, mm_scale);
|
mm_value = _mm_div_ps(mm_value, mm_scale);
|
||||||
_mm_storeu_ps(reinterpret_cast<Float32 *>(&out), mm_value);
|
_mm_storeu_ps(reinterpret_cast<Float32 *>(&out), mm_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool with_scale2 = with_scale>
|
||||||
|
static inline void compute(const Data & in, const Scale & mm_scale, Data & out,
|
||||||
|
typename std::enable_if<!with_scale2>::type * = nullptr)
|
||||||
|
{
|
||||||
|
__m128 mm_value = _mm_loadu_ps(reinterpret_cast<const Float32 *>(&in));
|
||||||
|
mm_value = _mm_round_ps(mm_value, rounding_mode);
|
||||||
|
_mm_storeu_ps(reinterpret_cast<Float32 *>(&out), mm_value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int rounding_mode>
|
template<int rounding_mode, bool with_scale>
|
||||||
struct RoundingComputation<Float64, rounding_mode>
|
struct RoundingComputation<Float64, rounding_mode, with_scale>
|
||||||
{
|
{
|
||||||
using Data = std::array<Float64, 2>;
|
using Data = std::array<Float64, 2>;
|
||||||
using Scale = __m128d;
|
using Scale = __m128d;
|
||||||
|
|
||||||
static inline void prepareScale(size_t scale, Scale & mm_scale)
|
template<bool with_scale2 = with_scale>
|
||||||
|
static inline void prepareScale(size_t scale, Scale & mm_scale,
|
||||||
|
typename std::enable_if<with_scale2>::type * = nullptr)
|
||||||
{
|
{
|
||||||
Float64 fscale = static_cast<Float64>(scale);
|
Float64 fscale = static_cast<Float64>(scale);
|
||||||
mm_scale = _mm_load1_pd(&fscale);
|
mm_scale = _mm_load1_pd(&fscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void compute(const Data & in, const Scale & mm_scale, Data & out)
|
template<bool with_scale2 = with_scale>
|
||||||
|
static inline void prepareScale(size_t scale, Scale & mm_scale,
|
||||||
|
typename std::enable_if<!with_scale2>::type * = nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool with_scale2 = with_scale>
|
||||||
|
static inline void compute(const Data & in, const Scale & mm_scale, Data & out,
|
||||||
|
typename std::enable_if<with_scale2>::type * = nullptr)
|
||||||
{
|
{
|
||||||
__m128d mm_value = _mm_loadu_pd(reinterpret_cast<const Float64 *>(&in));
|
__m128d mm_value = _mm_loadu_pd(reinterpret_cast<const Float64 *>(&in));
|
||||||
mm_value = _mm_mul_pd(mm_value, mm_scale);
|
mm_value = _mm_mul_pd(mm_value, mm_scale);
|
||||||
@ -141,18 +170,27 @@ namespace DB
|
|||||||
mm_value = _mm_div_pd(mm_value, mm_scale);
|
mm_value = _mm_div_pd(mm_value, mm_scale);
|
||||||
_mm_storeu_pd(reinterpret_cast<Float64 *>(&out), mm_value);
|
_mm_storeu_pd(reinterpret_cast<Float64 *>(&out), mm_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool with_scale2 = with_scale>
|
||||||
|
static inline void compute(const Data & in, const Scale & mm_scale, Data & out,
|
||||||
|
typename std::enable_if<!with_scale2>::type * = nullptr)
|
||||||
|
{
|
||||||
|
__m128d mm_value = _mm_loadu_pd(reinterpret_cast<const Float64 *>(&in));
|
||||||
|
mm_value = _mm_round_pd(mm_value, rounding_mode);
|
||||||
|
_mm_storeu_pd(reinterpret_cast<Float64 *>(&out), mm_value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Реализация функций округления на высоком уровне.
|
/// Реализация функций округления на высоком уровне.
|
||||||
|
|
||||||
template<typename T, int rounding_mode, typename Enable = void>
|
template<typename T, int rounding_mode, bool with_scale, typename Enable = void>
|
||||||
struct FunctionRoundingImpl
|
struct FunctionRoundingImpl
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// В случае целочисленных значений не выполяется округления.
|
/// В случае целочисленных значений не выполяется округления.
|
||||||
template<typename T, int rounding_mode>
|
template<typename T, int rounding_mode, bool with_scale>
|
||||||
struct FunctionRoundingImpl<T, rounding_mode, typename std::enable_if<std::is_integral<T>::value>::type>
|
struct FunctionRoundingImpl<T, rounding_mode, with_scale, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||||
{
|
{
|
||||||
static inline void apply(const PODArray<T> & in, size_t scale, typename ColumnVector<T>::Container_t & out)
|
static inline void apply(const PODArray<T> & in, size_t scale, typename ColumnVector<T>::Container_t & out)
|
||||||
{
|
{
|
||||||
@ -167,11 +205,11 @@ namespace DB
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, int rounding_mode>
|
template<typename T, int rounding_mode, bool with_scale>
|
||||||
struct FunctionRoundingImpl<T, rounding_mode, typename std::enable_if<std::is_floating_point<T>::value>::type>
|
struct FunctionRoundingImpl<T, rounding_mode, with_scale, typename std::enable_if<std::is_floating_point<T>::value>::type>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using Op = RoundingComputation<T, rounding_mode>;
|
using Op = RoundingComputation<T, rounding_mode, with_scale>;
|
||||||
using Data = typename Op::Data;
|
using Data = typename Op::Data;
|
||||||
using Scale = typename Op::Scale;
|
using Scale = typename Op::Scale;
|
||||||
|
|
||||||
@ -347,21 +385,25 @@ namespace
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
bool executeForType(Block & block, const ColumnNumbers & arguments, size_t result)
|
bool executeForType(Block & block, const ColumnNumbers & arguments, size_t result)
|
||||||
{
|
{
|
||||||
using Op = FunctionRoundingImpl<T, rounding_mode>;
|
using OpWithScale = FunctionRoundingImpl<T, rounding_mode, true>;
|
||||||
|
using OpWithoutScale = FunctionRoundingImpl<T, rounding_mode, false>;
|
||||||
|
|
||||||
if (ColumnVector<T> * col = typeid_cast<ColumnVector<T> *>(&*block.getByPosition(arguments[0]).column))
|
if (ColumnVector<T> * col = typeid_cast<ColumnVector<T> *>(&*block.getByPosition(arguments[0]).column))
|
||||||
{
|
{
|
||||||
UInt8 precision = 0;
|
|
||||||
if (arguments.size() == 2)
|
|
||||||
precision = getPrecision<T>(block.getByPosition(arguments[1]).column);
|
|
||||||
|
|
||||||
ColumnVector<T> * col_res = new ColumnVector<T>;
|
ColumnVector<T> * col_res = new ColumnVector<T>;
|
||||||
block.getByPosition(result).column = col_res;
|
block.getByPosition(result).column = col_res;
|
||||||
|
|
||||||
typename ColumnVector<T>::Container_t & vec_res = col_res->getData();
|
typename ColumnVector<T>::Container_t & vec_res = col_res->getData();
|
||||||
vec_res.resize(col->getData().size());
|
vec_res.resize(col->getData().size());
|
||||||
|
|
||||||
Op::apply(col->getData(), PowersOf10::values[precision], vec_res);
|
UInt8 precision = 0;
|
||||||
|
if (arguments.size() == 2)
|
||||||
|
precision = getPrecision<T>(block.getByPosition(arguments[1]).column);
|
||||||
|
|
||||||
|
if (precision > 0)
|
||||||
|
OpWithScale::apply(col->getData(), PowersOf10::values[precision], vec_res);
|
||||||
|
else
|
||||||
|
OpWithoutScale::apply(col->getData(), 0, vec_res);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -371,7 +413,11 @@ namespace
|
|||||||
if (arguments.size() == 2)
|
if (arguments.size() == 2)
|
||||||
precision = getPrecision<T>(block.getByPosition(arguments[1]).column);
|
precision = getPrecision<T>(block.getByPosition(arguments[1]).column);
|
||||||
|
|
||||||
T res = Op::apply(col->getData(), PowersOf10::values[precision]);
|
T res;
|
||||||
|
if (precision > 0)
|
||||||
|
res = OpWithScale::apply(col->getData(), PowersOf10::values[precision]);
|
||||||
|
else
|
||||||
|
res = OpWithoutScale::apply(col->getData(), 0);
|
||||||
|
|
||||||
ColumnConst<T> * col_res = new ColumnConst<T>(col->size(), res);
|
ColumnConst<T> * col_res = new ColumnConst<T>(col->size(), res);
|
||||||
block.getByPosition(result).column = col_res;
|
block.getByPosition(result).column = col_res;
|
||||||
|
Loading…
Reference in New Issue
Block a user