Skip to content

Instantly share code, notes, and snippets.

@ershovio
Last active August 29, 2015 14:15
Show Gist options
  • Save ershovio/37801e011dd629bf00a8 to your computer and use it in GitHub Desktop.
Save ershovio/37801e011dd629bf00a8 to your computer and use it in GitHub Desktop.
simple hash functions using AVX instr
#include<iostream>
#include<immintrin.h>
__m256i const PRIMES[] = {
32416182577,
32416183169,
32416183781,
32416184263,
32416182583,
32416183193,
32416183783,
32416184329,
32416182637,
32416183229,
32416183801,
32416184347,
32416182779,
32416183421,
32416183981,
32416184611,
32416182817,
32416183439,
32416184011,
32416184707,
32416182859,
32416183469,
32416184027,
32416184729,
32416182899,
32416183477,
32416184041,
32416184741,
32416182923,
32416183493,
32416184051,
32416184761,
32416182937,
32416183507,
32416184063,
32416184767,
32416183069,
32416183711,
32416184159,
32416184971,
32416183099,
32416183721,
32416184233,
32416184989,
32416183103,
32416183769,
32416184249,
32416185001
};
//lookup array for shuffle(VPSHUFB instruction).
__m256i SHUFFLE[]{
_mm256_setr_epi8(26, 22, 25, 15, 30, 3, 7, 17, 31, 12, 19, 13, 23, 11, 6, 20, 27, 5, 14, 18, 1, 2, 10, 4, 9, 24, 8, 0, 29, 28, 16, 21),
_mm256_setr_epi8(11, 27, 12, 21, 13, 15, 5, 24, 22, 7, 2, 14, 29, 4, 16, 10, 17, 28, 8, 6, 19, 26, 1, 23, 9, 0, 31, 20, 30, 25, 3, 18),
_mm256_setr_epi8(28, 19, 17, 18, 11, 3, 24, 8, 25, 23, 30, 26, 27, 4, 22, 21, 2, 14, 0, 7, 20, 31, 10, 9, 1, 15, 5, 13, 6, 29, 16, 12),
_mm256_setr_epi8(25, 13, 22, 2, 17, 4, 19, 14, 23, 31, 5, 8, 12, 0, 20, 9, 11, 1, 3, 7, 26, 28, 21, 10, 16, 27, 18, 15, 24, 6, 30, 29),
_mm256_setr_epi8(23, 18, 25, 14, 7, 31, 24, 26, 22, 29, 11, 20, 12, 2, 8, 1, 3, 30, 9, 4, 10, 16, 5, 27, 6, 15, 19, 28, 13, 21, 0, 17),
_mm256_setr_epi8(25, 30, 3, 14, 22, 13, 28, 16, 21, 9, 27, 1, 23, 29, 18, 15, 5, 17, 24, 31, 6, 12, 20, 2, 8, 7, 4, 26, 11, 19, 10, 0),
_mm256_setr_epi8(28, 29, 31, 0, 27, 18, 16, 2, 15, 24, 22, 5, 17, 26, 10, 9, 8, 13, 1, 6, 11, 14, 4, 25, 7, 30, 19, 20, 3, 23, 21, 12),
_mm256_setr_epi8(3, 24, 26, 25, 9, 18, 14, 17, 28, 22, 10, 2, 11, 8, 6, 29, 20, 7, 19, 16, 1, 5, 12, 23, 0, 31, 27, 15, 4, 21, 13, 30)
};
int const NUM_OF_LOOPS = 64;
int const NUM_OF_BLOCKS = 128;
//generates one 4kb block
__m256i* generate_key(){
__m256i res[NUM_OF_BLOCKS];
srand(time(NULL));
int i = 0;
for (; i < NUM_OF_BLOCKS; ++i){
res[i] = _mm256_set_epi32(rand(), rand(), rand(), rand(), rand(), rand(), rand(), rand());
}
return res;
}
//using multiply - bad
__m256i hash_func1(__m256i * key, __m256i seed){
int i = 0;
__m256i hash = seed;
for (; i < NUM_OF_LOOPS; ++i){
hash = _mm256_xor_si256(hash, key[i]);
//_mm256_mul_epi32 умножает 32 битные числа!!! и надо разобраться со знаками - уже исправил
hash = _mm256_mul_epu32(hash, PRIMES[i]);
hash = _mm256_xor_si256(hash, key[i + 1]);
}
return hash;
};
//using shuffle
__m256i hash_func2(__m256i * key, __m256i seed){
int i = 0;
__m256i hash = seed;
for (; i < NUM_OF_LOOPS; ++i){
hash = _mm256_xor_si256(hash, key[i]);
hash = _mm256_xor_si256(_mm256_shuffle_epi8(key[i + 1], SHUFFLE[(i + 1) % 8]), hash);
//hash = _mm256_mul_epu32(hash, PRIMES[i]); // или _mm256_mulhi_epu16
hash = _mm256_xor_si256(hash, key[i + 1]);
//TODO лучше один раз SHUFFLE[i % 8] второй SHUFFLE[simple_8bit_hash(item)]
hash = _mm256_shuffle_epi8(hash, SHUFFLE[i % 8]);
}
return hash;
};
int main(){
__m256i *key = generate_key();
__m256i result = hash_func2(key, _mm256_set1_epi32(107));
result = hash_func2(key, _mm256_set1_epi32(107));
__m256i temp = key[0];
temp = result;
temp = hash_func1(key, _mm256_set1_epi32(107));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment