diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dbc414e0797f7cd274cb8112714bd6664c58fad..1d4478cfb341581544e76c969b2e0f149fe26257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,21 @@ if (OS_LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") endif () endif () +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # If we leave this optimization enabled, gcc-7 replaces a pair of SSE intrinsics (16 byte load, store) with a call to memcpy. It leads to slow code. This is compiler bug. + # It looks like this: + # + # (gdb) bt + #0 memcpy (destination=0x7faa6e9f1638, source=0x7faa81d9e9a8, size=16) at ../libs/libmemcpy/memcpy.h:11 + #1 0x0000000005341c5f in _mm_storeu_si128 (__B=..., __P=) at /usr/lib/gcc/x86_64-linux-gnu/7/include/emmintrin.h:720 + #2 memcpySmallAllowReadWriteOverflow15Impl (n=, src=, dst=) at ../dbms/src/Common/memcpySmall.h:37 + #3 memcpySmallAllowReadWriteOverflow15 (n=, src=, dst=) at ../dbms/src/Common/memcpySmall.h:52 + #4 extractKeysAndPlaceInPoolContiguous (pool=..., keys=..., key_columns=..., keys_size=, i=) at ../dbms/src/Interpreters/AggregationCommon.h:262 + + set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-tree-loop-distribute-patterns") + set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fno-tree-loop-distribute-patterns") +endif () + if (USE_STATIC_LIBRARIES AND HAVE_NO_PIE) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG_NO_PIE}") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAG_NO_PIE}") diff --git a/dbms/src/Interpreters/Aggregator.cpp b/dbms/src/Interpreters/Aggregator.cpp index 8fbbf2846a6ef362b223387602965c0c27ea82da..3bfff637be4580f4267589204f744c67678a2016 100644 --- a/dbms/src/Interpreters/Aggregator.cpp +++ b/dbms/src/Interpreters/Aggregator.cpp @@ -491,8 +491,8 @@ AggregatedDataVariants::Type Aggregator::chooseAggregationMethod() /** If it is possible to use 'concat' method due to one-to-one correspondense. Otherwise the method will be 'serialized'. */ - if (params.keys_size == num_contiguous_keys && num_fixed_contiguous_keys + 1 >= num_contiguous_keys) - return AggregatedDataVariants::Type::concat; +// if (params.keys_size == num_contiguous_keys && num_fixed_contiguous_keys + 1 >= num_contiguous_keys) +// return AggregatedDataVariants::Type::concat; /** For case with multiple strings, we use 'concat' method despite the fact, that correspondense is not one-to-one. * Concat will concatenate strings including its zero terminators. @@ -500,8 +500,8 @@ AggregatedDataVariants::Type Aggregator::chooseAggregationMethod() * For example, keys ('a\0b', 'c') and ('a', 'b\0c') will be aggregated as one key. * This is documented behaviour. It may be avoided by just switching to 'serialized' method, which is less efficient. */ - if (params.keys_size == num_fixed_contiguous_keys + num_string_keys) - return AggregatedDataVariants::Type::concat; +// if (params.keys_size == num_fixed_contiguous_keys + num_string_keys) +// return AggregatedDataVariants::Type::concat; return AggregatedDataVariants::Type::serialized; diff --git a/dbms/src/Interpreters/Aggregator.h b/dbms/src/Interpreters/Aggregator.h index 843f6b92d8c2924d814974fc7672d8900fea3ab0..eb4cc48caea319b441d592df3f28d45ad4b253f7 100644 --- a/dbms/src/Interpreters/Aggregator.h +++ b/dbms/src/Interpreters/Aggregator.h @@ -119,7 +119,7 @@ struct AggregationMethodOneNumber } /// Get the key from the key columns for insertion into the hash table. - Key getKey( + ALWAYS_INLINE Key getKey( const ColumnRawPtrs & /*key_columns*/, size_t /*keys_size*/, /// Number of key columns. size_t i, /// From which row of the block, get the key. @@ -137,13 +137,13 @@ struct AggregationMethodOneNumber /** Place additional data, if necessary, in case a new key was inserted into the hash table. */ - static void onNewKey(typename Data::value_type & /*value*/, size_t /*keys_size*/, StringRefs & /*keys*/, Arena & /*pool*/) + static ALWAYS_INLINE void onNewKey(typename Data::value_type & /*value*/, size_t /*keys_size*/, StringRefs & /*keys*/, Arena & /*pool*/) { } /** The action to be taken if the key is not new. For example, roll back the memory allocation in the pool. */ - static void onExistingKey(const Key & /*key*/, StringRefs & /*keys*/, Arena & /*pool*/) {} + static ALWAYS_INLINE void onExistingKey(const Key & /*key*/, StringRefs & /*keys*/, Arena & /*pool*/) {} /** Do not use optimization for consecutive keys. */ @@ -188,7 +188,7 @@ struct AggregationMethodString chars = &column_string.getChars(); } - Key getKey( + ALWAYS_INLINE Key getKey( const ColumnRawPtrs & /*key_columns*/, size_t /*keys_size*/, size_t i, @@ -205,12 +205,12 @@ struct AggregationMethodString static AggregateDataPtr & getAggregateData(Mapped & value) { return value; } static const AggregateDataPtr & getAggregateData(const Mapped & value) { return value; } - static void onNewKey(typename Data::value_type & value, size_t /*keys_size*/, StringRefs & /*keys*/, Arena & pool) + static ALWAYS_INLINE void onNewKey(typename Data::value_type & value, size_t /*keys_size*/, StringRefs & /*keys*/, Arena & pool) { value.first.data = pool.insert(value.first.data, value.first.size); } - static void onExistingKey(const Key & /*key*/, StringRefs & /*keys*/, Arena & /*pool*/) {} + static ALWAYS_INLINE void onExistingKey(const Key & /*key*/, StringRefs & /*keys*/, Arena & /*pool*/) {} static const bool no_consecutive_keys_optimization = false; @@ -251,7 +251,7 @@ struct AggregationMethodFixedString chars = &column_string.getChars(); } - Key getKey( + ALWAYS_INLINE Key getKey( const ColumnRawPtrs &, size_t, size_t i, @@ -266,12 +266,12 @@ struct AggregationMethodFixedString static AggregateDataPtr & getAggregateData(Mapped & value) { return value; } static const AggregateDataPtr & getAggregateData(const Mapped & value) { return value; } - static void onNewKey(typename Data::value_type & value, size_t, StringRefs &, Arena & pool) + static ALWAYS_INLINE void onNewKey(typename Data::value_type & value, size_t, StringRefs &, Arena & pool) { value.first.data = pool.insert(value.first.data, value.first.size); } - static void onExistingKey(const Key &, StringRefs &, Arena &) {} + static ALWAYS_INLINE void onExistingKey(const Key &, StringRefs &, Arena &) {} static const bool no_consecutive_keys_optimization = false; @@ -407,7 +407,7 @@ struct AggregationMethodKeysFixed Base::init(key_columns); } - Key getKey( + ALWAYS_INLINE Key getKey( const ColumnRawPtrs & key_columns, size_t keys_size, size_t i, @@ -428,11 +428,11 @@ struct AggregationMethodKeysFixed static AggregateDataPtr & getAggregateData(Mapped & value) { return value; } static const AggregateDataPtr & getAggregateData(const Mapped & value) { return value; } - static void onNewKey(typename Data::value_type &, size_t, StringRefs &, Arena &) + static ALWAYS_INLINE void onNewKey(typename Data::value_type &, size_t, StringRefs &, Arena &) { } - static void onExistingKey(const Key &, StringRefs &, Arena &) {} + static ALWAYS_INLINE void onExistingKey(const Key &, StringRefs &, Arena &) {} static const bool no_consecutive_keys_optimization = false; @@ -510,7 +510,7 @@ struct AggregationMethodConcat { } - Key getKey( + ALWAYS_INLINE Key getKey( const ColumnRawPtrs & key_columns, size_t keys_size, size_t i, @@ -525,11 +525,11 @@ struct AggregationMethodConcat static AggregateDataPtr & getAggregateData(Mapped & value) { return value; } static const AggregateDataPtr & getAggregateData(const Mapped & value) { return value; } - static void onNewKey(typename Data::value_type &, size_t, StringRefs &, Arena &) + static ALWAYS_INLINE void onNewKey(typename Data::value_type &, size_t, StringRefs &, Arena &) { } - static void onExistingKey(const Key & key, StringRefs & keys, Arena & pool) + static ALWAYS_INLINE void onExistingKey(const Key & key, StringRefs & keys, Arena & pool) { pool.rollback(key.size + keys.size() * sizeof(keys[0])); } @@ -595,7 +595,7 @@ struct AggregationMethodSerialized { } - Key getKey( + ALWAYS_INLINE Key getKey( const ColumnRawPtrs & key_columns, size_t keys_size, size_t i, @@ -610,11 +610,11 @@ struct AggregationMethodSerialized static AggregateDataPtr & getAggregateData(Mapped & value) { return value; } static const AggregateDataPtr & getAggregateData(const Mapped & value) { return value; } - static void onNewKey(typename Data::value_type &, size_t, StringRefs &, Arena &) + static ALWAYS_INLINE void onNewKey(typename Data::value_type &, size_t, StringRefs &, Arena &) { } - static void onExistingKey(const Key & key, StringRefs &, Arena & pool) + static ALWAYS_INLINE void onExistingKey(const Key & key, StringRefs &, Arena & pool) { pool.rollback(key.size); } @@ -654,7 +654,7 @@ struct AggregationMethodHashed { } - Key getKey( + ALWAYS_INLINE Key getKey( const ColumnRawPtrs & key_columns, size_t keys_size, size_t i, @@ -669,12 +669,12 @@ struct AggregationMethodHashed static AggregateDataPtr & getAggregateData(Mapped & value) { return value.second; } static const AggregateDataPtr & getAggregateData(const Mapped & value) { return value.second; } - static void onNewKey(typename Data::value_type & value, size_t keys_size, StringRefs & keys, Arena & pool) + static ALWAYS_INLINE void onNewKey(typename Data::value_type & value, size_t keys_size, StringRefs & keys, Arena & pool) { value.second.first = placeKeysInPool(keys_size, keys, pool); } - static void onExistingKey(const Key &, StringRefs &, Arena &) {} + static ALWAYS_INLINE void onExistingKey(const Key &, StringRefs &, Arena &) {} static const bool no_consecutive_keys_optimization = false;