Little better [#CLICKHOUSE-2].

This commit is contained in:
Alexey Milovidov 2017-06-23 09:45:48 +03:00
parent 6b075fdcbe
commit 3c33f1841f
3 changed files with 46 additions and 1 deletions

View File

@ -38,6 +38,8 @@ size_t countBytesInFilter(const IColumn::Filter & filt)
| (static_cast<UInt64>(_mm_movemask_epi8(_mm_cmpgt_epi8(
_mm_loadu_si128(reinterpret_cast<const __m128i *>(pos + 48)),
zero16))) << 48));
/// TODO Add duff device for tail?
#endif
for (; pos < end; ++pos)
@ -47,6 +49,44 @@ size_t countBytesInFilter(const IColumn::Filter & filt)
}
/** clang 4 generates better code than gcc 6.
* And both gcc and clang could not vectorize trivial loop by bytes automatically.
*/
bool memoryIsZero(const void * data, size_t size)
{
const Int8 * pos = reinterpret_cast<const Int8 *>(data);
const Int8 * end = pos + size;
#if __SSE2__
const __m128 zero16 = _mm_setzero_ps();
const Int8 * end64 = pos + size / 64 * 64;
for (; pos < end64; pos += 64)
if (_mm_movemask_ps(_mm_cmpneq_ps(
_mm_loadu_ps(reinterpret_cast<const float *>(pos)),
zero16))
| _mm_movemask_ps(_mm_cmpneq_ps(
_mm_loadu_ps(reinterpret_cast<const float *>(pos + 16)),
zero16))
| _mm_movemask_ps(_mm_cmpneq_ps(
_mm_loadu_ps(reinterpret_cast<const float *>(pos + 32)),
zero16))
| _mm_movemask_ps(_mm_cmpneq_ps(
_mm_loadu_ps(reinterpret_cast<const float *>(pos + 48)),
zero16)))
return false;
/// TODO Add duff device for tail?
#endif
for (; pos < end; ++pos)
if (*pos)
return false;
return true;
}
namespace ErrorCodes
{
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;

View File

@ -11,6 +11,9 @@ namespace DB
/// Counts how many bytes of `filt` are greater than zero.
size_t countBytesInFilter(const IColumn::Filter & filt);
/// Returns true, if the memory contains only zeros.
bool memoryIsZero(const void * data, size_t size);
/// The general implementation of `filter` function for ColumnArray and ColumnString.
template <typename T>

View File

@ -1,8 +1,10 @@
#include <DataStreams/NullableAdapterBlockInputStream.h>
#include <Columns/ColumnNullable.h>
#include <Columns/ColumnsCommon.h>
#include <DataTypes/DataTypeNullable.h>
#include <DataStreams/isConvertableTypes.h>
namespace DB
{
@ -51,7 +53,7 @@ Block NullableAdapterBlockInputStream::readImpl()
const auto & nullable_type = static_cast<const DataTypeNullable &>(*elem.type);
const auto & null_map = nullable_col.getNullMap();
bool has_nulls = std::any_of(null_map.begin(), null_map.end(), [](UInt8 val){ return val == 1; });
bool has_nulls = !memoryIsZero(null_map.data(), null_map.size());
if (has_nulls)
throw Exception{"Cannot insert NULL value into non-nullable column",