324 lines
5.9 KiB
C++
324 lines
5.9 KiB
C++
|
|
//#define POPCNT_LOOKUP
|
|
|
|
#ifdef POPCNT_LOOKUP
|
|
|
|
uint16_t lookup[65536];
|
|
|
|
// The lookup table replaces 2 x popcount and 2 x shift with 1 bit-or and 2 x memory fetch
|
|
void prepare_lookup() {
|
|
for (int i=0; i < 65536; i++) {
|
|
lookup[i] = 1 << _mm_popcnt_u32(i);
|
|
}
|
|
}
|
|
#define STEP(unused) { \
|
|
const __m512i b = _mm512_permutexvar_epi32(index, v); \
|
|
index = _mm512_add_epi32(index, incr); \
|
|
const uint16_t lt = _mm512_mask_cmplt_epi32_mask(sort_mask, v, b); \
|
|
const uint16_t eq = _mm512_mask_cmpeq_epi32_mask(sort_mask, v, b); \
|
|
const uint16_t mask = lookup[lt | eq] - lookup[lt]; \
|
|
result = _mm512_mask_mov_epi32(result, mask, b); \
|
|
}
|
|
|
|
#else
|
|
|
|
#define STEP(unused) { \
|
|
const __m512i b = _mm512_permutexvar_epi32(index, v); \
|
|
index = _mm512_add_epi32(index, incr); \
|
|
const uint16_t lt = _mm_popcnt_u32(_mm512_mask_cmplt_epi32_mask(sort_mask, v, b)); \
|
|
const uint16_t eq = _mm_popcnt_u32(_mm512_mask_cmpeq_epi32_mask(sort_mask, v, b)); \
|
|
const uint16_t mask = (uint32_t(1) << (lt + eq)) - (uint32_t(1) << lt); \
|
|
result = _mm512_mask_mov_epi32(result, mask, b); \
|
|
}
|
|
|
|
#endif
|
|
|
|
__m512i avx512_sort16_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0xffff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
STEP(8);
|
|
STEP(9);
|
|
STEP(10);
|
|
STEP(11);
|
|
STEP(12);
|
|
STEP(13);
|
|
STEP(14);
|
|
STEP(15);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort15_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x7fff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
STEP(8);
|
|
STEP(9);
|
|
STEP(10);
|
|
STEP(11);
|
|
STEP(12);
|
|
STEP(13);
|
|
STEP(14);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort14_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x3fff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
STEP(8);
|
|
STEP(9);
|
|
STEP(10);
|
|
STEP(11);
|
|
STEP(12);
|
|
STEP(13);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort13_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x1fff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
STEP(8);
|
|
STEP(9);
|
|
STEP(10);
|
|
STEP(11);
|
|
STEP(12);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort12_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x0fff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
STEP(8);
|
|
STEP(9);
|
|
STEP(10);
|
|
STEP(11);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort11_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x07ff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
STEP(8);
|
|
STEP(9);
|
|
STEP(10);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort10_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x03ff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
STEP(8);
|
|
STEP(9);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort9_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x01ff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
STEP(8);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort8_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x00ff;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
STEP(7);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort7_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x007f;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
STEP(6);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort6_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x003f;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
STEP(5);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort5_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x001f;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
STEP(4);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort4_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x000f;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
STEP(3);
|
|
|
|
return result;
|
|
}
|
|
|
|
__m512i avx512_sort3_epi32(const __m512i v) {
|
|
|
|
__m512i result = v;
|
|
__m512i index = _mm512_setzero_si512();
|
|
__m512i incr = _mm512_set1_epi32(1);
|
|
|
|
const uint16_t sort_mask = 0x0007;
|
|
STEP(0);
|
|
STEP(1);
|
|
STEP(2);
|
|
|
|
return result;
|
|
}
|
|
|
|
#undef STEP
|