magyarsort/simd-sort/avx512-sort-register.cpp

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