farmhashte.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #include "common.h"
  2. namespace {
  3. #include "farmhashxo.cc"
  4. }
  5. namespace farmhashte {
  6. #if !can_use_sse41 || !x86_64
  7. uint64_t Hash64(const char *s, size_t len) {
  8. FARMHASH_DIE_IF_MISCONFIGURED;
  9. return s == NULL ? 0 : len;
  10. }
  11. uint64_t Hash64WithSeed(const char *s, size_t len, uint64_t seed) {
  12. FARMHASH_DIE_IF_MISCONFIGURED;
  13. return seed + Hash64(s, len);
  14. }
  15. uint64_t Hash64WithSeeds(const char *s, size_t len,
  16. uint64_t seed0, uint64_t seed1) {
  17. FARMHASH_DIE_IF_MISCONFIGURED;
  18. return seed0 + seed1 + Hash64(s, len);
  19. }
  20. #else
  21. #undef Fetch
  22. #define Fetch Fetch64
  23. #undef Rotate
  24. #define Rotate Rotate64
  25. #undef Bswap
  26. #define Bswap Bswap64
  27. // Helpers for data-parallel operations (1x 128 bits or 2x 64 or 4x 32).
  28. STATIC_INLINE __m128i Add(__m128i x, __m128i y) { return _mm_add_epi64(x, y); }
  29. STATIC_INLINE __m128i Xor(__m128i x, __m128i y) { return _mm_xor_si128(x, y); }
  30. STATIC_INLINE __m128i Mul(__m128i x, __m128i y) { return _mm_mullo_epi32(x, y); }
  31. STATIC_INLINE __m128i Shuf(__m128i x, __m128i y) { return _mm_shuffle_epi8(y, x); }
  32. // Requires n >= 256. Requires SSE4.1. Should be slightly faster if the
  33. // compiler uses AVX instructions (e.g., use the -mavx flag with GCC).
  34. STATIC_INLINE uint64_t Hash64Long(const char* s, size_t n,
  35. uint64_t seed0, uint64_t seed1) {
  36. const __m128i kShuf =
  37. _mm_set_epi8(4, 11, 10, 5, 8, 15, 6, 9, 12, 2, 14, 13, 0, 7, 3, 1);
  38. const __m128i kMult =
  39. _mm_set_epi8(0xbd, 0xd6, 0x33, 0x39, 0x45, 0x54, 0xfa, 0x03,
  40. 0x34, 0x3e, 0x33, 0xed, 0xcc, 0x9e, 0x2d, 0x51);
  41. uint64_t seed2 = (seed0 + 113) * (seed1 + 9);
  42. uint64_t seed3 = (Rotate(seed0, 23) + 27) * (Rotate(seed1, 30) + 111);
  43. __m128i d0 = _mm_cvtsi64_si128(seed0);
  44. __m128i d1 = _mm_cvtsi64_si128(seed1);
  45. __m128i d2 = Shuf(kShuf, d0);
  46. __m128i d3 = Shuf(kShuf, d1);
  47. __m128i d4 = Xor(d0, d1);
  48. __m128i d5 = Xor(d1, d2);
  49. __m128i d6 = Xor(d2, d4);
  50. __m128i d7 = _mm_set1_epi32(seed2 >> 32);
  51. __m128i d8 = Mul(kMult, d2);
  52. __m128i d9 = _mm_set1_epi32(seed3 >> 32);
  53. __m128i d10 = _mm_set1_epi32(seed3);
  54. __m128i d11 = Add(d2, _mm_set1_epi32(seed2));
  55. const char* end = s + (n & ~static_cast<size_t>(255));
  56. do {
  57. __m128i z;
  58. z = Fetch128(s);
  59. d0 = Add(d0, z);
  60. d1 = Shuf(kShuf, d1);
  61. d2 = Xor(d2, d0);
  62. d4 = Xor(d4, z);
  63. d4 = Xor(d4, d1);
  64. std::swap(d0, d6);
  65. z = Fetch128(s + 16);
  66. d5 = Add(d5, z);
  67. d6 = Shuf(kShuf, d6);
  68. d8 = Shuf(kShuf, d8);
  69. d7 = Xor(d7, d5);
  70. d0 = Xor(d0, z);
  71. d0 = Xor(d0, d6);
  72. std::swap(d5, d11);
  73. z = Fetch128(s + 32);
  74. d1 = Add(d1, z);
  75. d2 = Shuf(kShuf, d2);
  76. d4 = Shuf(kShuf, d4);
  77. d5 = Xor(d5, z);
  78. d5 = Xor(d5, d2);
  79. std::swap(d10, d4);
  80. z = Fetch128(s + 48);
  81. d6 = Add(d6, z);
  82. d7 = Shuf(kShuf, d7);
  83. d0 = Shuf(kShuf, d0);
  84. d8 = Xor(d8, d6);
  85. d1 = Xor(d1, z);
  86. d1 = Add(d1, d7);
  87. z = Fetch128(s + 64);
  88. d2 = Add(d2, z);
  89. d5 = Shuf(kShuf, d5);
  90. d4 = Add(d4, d2);
  91. d6 = Xor(d6, z);
  92. d6 = Xor(d6, d11);
  93. std::swap(d8, d2);
  94. z = Fetch128(s + 80);
  95. d7 = Xor(d7, z);
  96. d8 = Shuf(kShuf, d8);
  97. d1 = Shuf(kShuf, d1);
  98. d0 = Add(d0, d7);
  99. d2 = Add(d2, z);
  100. d2 = Add(d2, d8);
  101. std::swap(d1, d7);
  102. z = Fetch128(s + 96);
  103. d4 = Shuf(kShuf, d4);
  104. d6 = Shuf(kShuf, d6);
  105. d8 = Mul(kMult, d8);
  106. d5 = Xor(d5, d11);
  107. d7 = Xor(d7, z);
  108. d7 = Add(d7, d4);
  109. std::swap(d6, d0);
  110. z = Fetch128(s + 112);
  111. d8 = Add(d8, z);
  112. d0 = Shuf(kShuf, d0);
  113. d2 = Shuf(kShuf, d2);
  114. d1 = Xor(d1, d8);
  115. d10 = Xor(d10, z);
  116. d10 = Xor(d10, d0);
  117. std::swap(d11, d5);
  118. z = Fetch128(s + 128);
  119. d4 = Add(d4, z);
  120. d5 = Shuf(kShuf, d5);
  121. d7 = Shuf(kShuf, d7);
  122. d6 = Add(d6, d4);
  123. d8 = Xor(d8, z);
  124. d8 = Xor(d8, d5);
  125. std::swap(d4, d10);
  126. z = Fetch128(s + 144);
  127. d0 = Add(d0, z);
  128. d1 = Shuf(kShuf, d1);
  129. d2 = Add(d2, d0);
  130. d4 = Xor(d4, z);
  131. d4 = Xor(d4, d1);
  132. z = Fetch128(s + 160);
  133. d5 = Add(d5, z);
  134. d6 = Shuf(kShuf, d6);
  135. d8 = Shuf(kShuf, d8);
  136. d7 = Xor(d7, d5);
  137. d0 = Xor(d0, z);
  138. d0 = Xor(d0, d6);
  139. std::swap(d2, d8);
  140. z = Fetch128(s + 176);
  141. d1 = Add(d1, z);
  142. d2 = Shuf(kShuf, d2);
  143. d4 = Shuf(kShuf, d4);
  144. d5 = Mul(kMult, d5);
  145. d5 = Xor(d5, z);
  146. d5 = Xor(d5, d2);
  147. std::swap(d7, d1);
  148. z = Fetch128(s + 192);
  149. d6 = Add(d6, z);
  150. d7 = Shuf(kShuf, d7);
  151. d0 = Shuf(kShuf, d0);
  152. d8 = Add(d8, d6);
  153. d1 = Xor(d1, z);
  154. d1 = Xor(d1, d7);
  155. std::swap(d0, d6);
  156. z = Fetch128(s + 208);
  157. d2 = Add(d2, z);
  158. d5 = Shuf(kShuf, d5);
  159. d4 = Xor(d4, d2);
  160. d6 = Xor(d6, z);
  161. d6 = Xor(d6, d9);
  162. std::swap(d5, d11);
  163. z = Fetch128(s + 224);
  164. d7 = Add(d7, z);
  165. d8 = Shuf(kShuf, d8);
  166. d1 = Shuf(kShuf, d1);
  167. d0 = Xor(d0, d7);
  168. d2 = Xor(d2, z);
  169. d2 = Xor(d2, d8);
  170. std::swap(d10, d4);
  171. z = Fetch128(s + 240);
  172. d3 = Add(d3, z);
  173. d4 = Shuf(kShuf, d4);
  174. d6 = Shuf(kShuf, d6);
  175. d7 = Mul(kMult, d7);
  176. d5 = Add(d5, d3);
  177. d7 = Xor(d7, z);
  178. d7 = Xor(d7, d4);
  179. std::swap(d3, d9);
  180. s += 256;
  181. } while (s != end);
  182. d6 = Add(Mul(kMult, d6), _mm_cvtsi64_si128(n));
  183. if (n % 256 != 0) {
  184. d7 = Add(_mm_shuffle_epi32(d8, (0 << 6) + (3 << 4) + (2 << 2) + (1 << 0)), d7);
  185. d8 = Add(Mul(kMult, d8), _mm_cvtsi64_si128(farmhashxo::Hash64(s, n % 256)));
  186. }
  187. __m128i t[8];
  188. d0 = Mul(kMult, Shuf(kShuf, Mul(kMult, d0)));
  189. d3 = Mul(kMult, Shuf(kShuf, Mul(kMult, d3)));
  190. d9 = Mul(kMult, Shuf(kShuf, Mul(kMult, d9)));
  191. d1 = Mul(kMult, Shuf(kShuf, Mul(kMult, d1)));
  192. d0 = Add(d11, d0);
  193. d3 = Xor(d7, d3);
  194. d9 = Add(d8, d9);
  195. d1 = Add(d10, d1);
  196. d4 = Add(d3, d4);
  197. d5 = Add(d9, d5);
  198. d6 = Xor(d1, d6);
  199. d2 = Add(d0, d2);
  200. t[0] = d0;
  201. t[1] = d3;
  202. t[2] = d9;
  203. t[3] = d1;
  204. t[4] = d4;
  205. t[5] = d5;
  206. t[6] = d6;
  207. t[7] = d2;
  208. return farmhashxo::Hash64(reinterpret_cast<const char*>(t), sizeof(t));
  209. }
  210. uint64_t Hash64(const char *s, size_t len) {
  211. // Empirically, farmhashxo seems faster until length 512.
  212. return len >= 512 ? Hash64Long(s, len, k2, k1) : farmhashxo::Hash64(s, len);
  213. }
  214. uint64_t Hash64WithSeed(const char *s, size_t len, uint64_t seed) {
  215. return len >= 512 ? Hash64Long(s, len, k1, seed) :
  216. farmhashxo::Hash64WithSeed(s, len, seed);
  217. }
  218. uint64_t Hash64WithSeeds(const char *s, size_t len, uint64_t seed0, uint64_t seed1) {
  219. return len >= 512 ? Hash64Long(s, len, seed0, seed1) :
  220. farmhashxo::Hash64WithSeeds(s, len, seed0, seed1);
  221. }
  222. #endif
  223. } // namespace farmhashte