|
26 | 26 | #ifndef LL_LLUUID_H |
27 | 27 | #define LL_LLUUID_H |
28 | 28 |
|
29 | | -#include "llpreprocessor.h" |
30 | | - |
31 | 29 | #include <iostream> |
32 | 30 | #include <set> |
33 | 31 | #include <vector> |
34 | 32 | #include "stdtypes.h" |
| 33 | +#include "llpreprocessor.h" |
35 | 34 | #include <boost/functional/hash.hpp> |
36 | 35 |
|
37 | | -#if LL_ARM64 |
38 | | -#include "sse2neon.h" |
39 | | -#elif LL_X86 |
40 | | -#include <immintrin.h> |
41 | | -#endif |
42 | | - |
43 | 36 | class LLMutex; |
44 | 37 |
|
45 | 38 | const S32 UUID_BYTES = 16; |
@@ -83,15 +76,6 @@ class LL_COMMON_API LLUUID |
83 | 76 | // |
84 | 77 | // ACCESSORS |
85 | 78 | // |
86 | | - |
87 | | - // BEGIN BOOST |
88 | | - // Contains code from the Boost Library with license below. |
89 | | - /* |
90 | | - * Copyright Andrey Semashev 2013. |
91 | | - * Distributed under the Boost Software License, Version 1.0. |
92 | | - * (See accompanying file LICENSE_1_0.txt or copy at |
93 | | - * http://www.boost.org/LICENSE_1_0.txt) |
94 | | - */ |
95 | 79 | private: |
96 | 80 | // Derived from Boost.UUID hash impl |
97 | 81 | inline std::uint64_t hash_mix_mx( std::uint64_t x ) const noexcept |
@@ -135,97 +119,17 @@ class LL_COMMON_API LLUUID |
135 | 119 | return id.getHash(); |
136 | 120 | } |
137 | 121 |
|
138 | | -#if defined(LL_X86) || defined(LL_ARM64) |
139 | | - LL_FORCE_INLINE __m128i load_unaligned_si128(const U8* p) const |
140 | | - { |
141 | | - return _mm_loadu_si128(reinterpret_cast<const __m128i*>(p)); |
142 | | - } |
143 | | - |
144 | | - bool isNull() const // Faster than comparing to LLUUID::null. |
145 | | - { |
146 | | - __m128i mm = load_unaligned_si128(mData); |
147 | | -#if defined(__AVX2__) || defined(__SSE4_1__) || defined(LL_ARM64) |
148 | | - return _mm_test_all_zeros(mm, mm) != 0; |
149 | | -#else |
150 | | - mm = _mm_cmpeq_epi32(mm, _mm_setzero_si128()); |
151 | | - return _mm_movemask_epi8(mm) == 0xFFFF; |
152 | | -#endif |
153 | | - } |
154 | | - |
155 | | - bool notNull() const // Faster than comparing to LLUUID::null. |
156 | | - { |
157 | | - return !isNull(); |
158 | | - } |
| 122 | + bool isNull() const; // Faster than comparing to LLUUID::null. |
| 123 | + bool notNull() const; // Faster than comparing to LLUUID::null. |
159 | 124 | // JC: This is dangerous. It allows UUIDs to be cast automatically |
160 | 125 | // to integers, among other things. Use isNull() or notNull(). |
161 | 126 | // operator bool() const; |
162 | 127 |
|
163 | | - bool operator==(const LLUUID& rhs) const |
164 | | - { |
165 | | - __m128i mm_left = load_unaligned_si128(mData); |
166 | | - __m128i mm_right = load_unaligned_si128(rhs.mData); |
167 | | - |
168 | | -#if defined(__AVX2__) || defined(__SSE4_1__) || defined(LL_ARM64) |
169 | | - __m128i mm = _mm_xor_si128(mm_left, mm_right); |
170 | | - return _mm_test_all_zeros(mm, mm) != 0; |
171 | | -#else |
172 | | - __m128i mm_cmp = _mm_cmpeq_epi32(mm_left, mm_right); |
173 | | - return _mm_movemask_epi8(mm_cmp) == 0xFFFF; |
174 | | -#endif |
175 | | - } |
176 | | - |
177 | | - bool operator!=(const LLUUID& rhs) const |
178 | | - { |
179 | | - return !((*this) == rhs); |
180 | | - } |
181 | | - |
182 | | - bool operator<(const LLUUID& rhs) const |
183 | | - { |
184 | | - __m128i mm_left = load_unaligned_si128(mData); |
185 | | - __m128i mm_right = load_unaligned_si128(rhs.mData); |
186 | | - |
187 | | - // To emulate lexicographical_compare behavior we have to perform two comparisons - the forward and reverse one. |
188 | | - // Then we know which bytes are equivalent and which ones are different, and for those different the comparison results |
189 | | - // will be opposite. Then we'll be able to find the first differing comparison result (for both forward and reverse ways), |
190 | | - // and depending on which way it is for, this will be the result of the operation. There are a few notes to consider: |
191 | | - // |
192 | | - // 1. Due to little endian byte order the first bytes go into the lower part of the xmm registers, |
193 | | - // so the comparison results in the least significant bits will actually be the most signigicant for the final operation result. |
194 | | - // This means we have to determine which of the comparison results have the least significant bit on, and this is achieved with |
195 | | - // the "(x - 1) ^ x" trick. |
196 | | - // 2. Because there is only signed comparison in SSE/AVX, we have to invert byte comparison results whenever signs of the corresponding |
197 | | - // bytes are different. I.e. in signed comparison it's -1 < 1, but in unsigned it is the opposite (255 > 1). To do that we XOR left and right, |
198 | | - // making the most significant bit of each byte 1 if the signs are different, and later apply this mask with another XOR to the comparison results. |
199 | | - // 3. pcmpgtw compares for "greater" relation, so we swap the arguments to get what we need. |
200 | | - |
201 | | - const __m128i mm_signs_mask = _mm_xor_si128(mm_left, mm_right); |
202 | | - |
203 | | - __m128i mm_cmp = _mm_cmpgt_epi8(mm_right, mm_left), mm_rcmp = _mm_cmpgt_epi8(mm_left, mm_right); |
204 | | - |
205 | | - mm_cmp = _mm_xor_si128(mm_signs_mask, mm_cmp); |
206 | | - mm_rcmp = _mm_xor_si128(mm_signs_mask, mm_rcmp); |
207 | 128 |
|
208 | | - uint32_t cmp = static_cast<uint32_t>(_mm_movemask_epi8(mm_cmp)), rcmp = static_cast<uint32_t>(_mm_movemask_epi8(mm_rcmp)); |
209 | | - |
210 | | - cmp = (cmp - 1u) ^ cmp; |
211 | | - rcmp = (rcmp - 1u) ^ rcmp; |
212 | | - |
213 | | - return cmp < rcmp; |
214 | | - } |
215 | | - |
216 | | - bool operator>(const LLUUID& rhs) const |
217 | | - { |
218 | | - return rhs < (*this); |
219 | | - } |
220 | | - // END BOOST |
221 | | -#else // Non-intrinsic path |
222 | | - bool isNull() const; // Faster than comparing to LLUUID::null. |
223 | | - bool notNull() const; // Faster than comparing to LLUUID::null. |
224 | | - bool operator==(const LLUUID& rhs) const; |
225 | | - bool operator!=(const LLUUID& rhs) const; |
226 | | - bool operator<(const LLUUID& rhs) const; |
227 | | - bool operator>(const LLUUID& rhs) const; |
228 | | -#endif |
| 129 | + bool operator==(const LLUUID &rhs) const; |
| 130 | + bool operator!=(const LLUUID &rhs) const; |
| 131 | + bool operator<(const LLUUID &rhs) const; |
| 132 | + bool operator>(const LLUUID &rhs) const; |
229 | 133 |
|
230 | 134 | // xor functions. Useful since any two random uuids xored together |
231 | 135 | // will yield a determinate third random unique id that can be |
|
0 commit comments