From 805a82ee4398e429814df8257fa393965525db17 Mon Sep 17 00:00:00 2001 From: Jason Carey Date: Fri, 9 Sep 2016 13:33:07 -0400 Subject: SERVER-23506 Vectorized fts char scan for ppc64le Acceleration via ppc64le altivec support for full text search --- src/mongo/db/fts/unicode/byte_vector.h | 2 + src/mongo/db/fts/unicode/byte_vector_altivec.h | 160 +++++++++++++++++++++++++ src/mongo/db/fts/unicode/byte_vector_sse2.h | 2 + 3 files changed, 164 insertions(+) create mode 100644 src/mongo/db/fts/unicode/byte_vector_altivec.h diff --git a/src/mongo/db/fts/unicode/byte_vector.h b/src/mongo/db/fts/unicode/byte_vector.h index d361a857ff1..2404e15dfda 100644 --- a/src/mongo/db/fts/unicode/byte_vector.h +++ b/src/mongo/db/fts/unicode/byte_vector.h @@ -33,6 +33,8 @@ // TODO replace this with #if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE2_VERSION in boost 1.60 #if defined(_M_AMD64) || defined(__amd64__) #include "mongo/db/fts/unicode/byte_vector_sse2.h" +#elif defined(__powerpc64__) +#include "mongo/db/fts/unicode/byte_vector_altivec.h" #else // Other platforms go above here. #undef MONGO_HAVE_FAST_BYTE_VECTOR #endif diff --git a/src/mongo/db/fts/unicode/byte_vector_altivec.h b/src/mongo/db/fts/unicode/byte_vector_altivec.h new file mode 100644 index 00000000000..f7a07ac0743 --- /dev/null +++ b/src/mongo/db/fts/unicode/byte_vector_altivec.h @@ -0,0 +1,160 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include +#undef vector +#undef bool + +#include + +#include "mongo/platform/bits.h" + +namespace mongo { +namespace unicode { + +/** + * A sequence of bytes that can be manipulated using vectorized instructions. + * + * This is specific to the use case in mongo::unicode::String and not intended as a general purpose + * vector class. + * + * This specialization offers acceleration for ppc64le + */ +class ByteVector { +public: + using Native = __vector signed char; + + // Logically 16 bits, but this is the actual output type of vec_vbpermq + using Mask = uint64_t; + + using Scalar = int8_t; + static const int size = sizeof(Native); + + /** + * Sets all bytes to 0. + */ + ByteVector() { + _data = vec_splat_s8(0); + } + + /** + * Sets all bytes to val. + */ + explicit ByteVector(Scalar val) { + _data = vec_splats(val); + } + + /** + * Load a vector from a potentially unaligned location. + */ + static ByteVector load(const void* ptr) { + // This function is documented as taking an unaligned pointer. + return vec_vsx_ld(0, reinterpret_cast(ptr)); + } + + /** + * Store this vector to a potentially unaligned location. + */ + void store(void* ptr) const { + // This function is documented as taking an unaligned pointer. + vec_vsx_st(_data, 0, reinterpret_cast(ptr)); + } + + /** + * Returns a bitmask with the high bit from each byte. + */ + Mask maskHigh() const { + // The bits array represents the api indexes of the left to right high bits. + // + // This seems really wrong, but the indexes you hand to vec_vbpermq are actually mirrored on + // little endian (the interface seems more designed for big endian). You'd do 7, 15, etc on + // big endian by comparison. + const Native bits = {120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0}; + + return vec_extract(vec_vbpermq(_data, bits), 0); + } + + /** + * Returns a bitmask with any bit from each byte. + * + * This operation only makes sense if all bytes are either 0x00 or 0xff, such as the result from + * comparison operations. + */ + Mask maskAny() const { + return maskHigh(); // Other archs may be more efficient here. + } + + /** + * Counts zero bits in mask from whichever side corresponds to the lowest memory address. + */ + static uint32_t countInitialZeros(Mask mask) { + return mask == 0 ? size : countTrailingZeros64(mask); + } + + /** + * Sets each byte to 0xff if it is ==(EQ), <(LT), or >(GT), otherwise 0x00. + * + * May use either signed or unsigned comparisons since this use case doesn't care about bytes + * with high bit set. + */ + ByteVector compareEQ(Scalar val) const { + return (Native)vec_cmpeq(_data, ByteVector(val)._data); + } + ByteVector compareLT(Scalar val) const { + return (Native)vec_cmplt(_data, ByteVector(val)._data); + } + ByteVector compareGT(Scalar val) const { + return (Native)vec_cmpgt(_data, ByteVector(val)._data); + } + + ByteVector operator|(ByteVector other) const { + return (Native)vec_or(_data, other._data); + } + + ByteVector& operator|=(ByteVector other) { + return (*this = (*this | other)); + } + + ByteVector operator&(ByteVector other) const { + return (Native)vec_and(_data, other._data); + } + + ByteVector& operator&=(ByteVector other) { + return (*this = (*this & other)); + } + +private: + ByteVector(Native data) : _data(data) {} + + Native _data; +}; + +} // namespace unicode +} // namespace mongo diff --git a/src/mongo/db/fts/unicode/byte_vector_sse2.h b/src/mongo/db/fts/unicode/byte_vector_sse2.h index 6262488085a..7a44dd31e92 100644 --- a/src/mongo/db/fts/unicode/byte_vector_sse2.h +++ b/src/mongo/db/fts/unicode/byte_vector_sse2.h @@ -41,6 +41,8 @@ namespace unicode { * * This is specific to the use case in mongo::unicode::String and not intended as a general purpose * vector class. + * + * This specialization offers acceleration for x86_64 */ class ByteVector { public: -- cgit v1.2.1