Unsigned integers can be compressed by using "bit-packing" techniques: Within a block of unsigned integers only the significant bits are stored, resulting in data compression when all integers in a block are "small". The method is known as FOR (frame of reference).
There are SIMD libraries that do this very efficiently.
Now I want to use FOR-like techniques to encode signed integers, e.g. from a differenced sequence of unsorted unsigned integers. The sign of each signed integer needs to be stored somewhere, there are two options:
- Store the signs in a separate block of data. This adds overhead.
- Store the sign together with the absolute value of each signed integer.
I'm following path 2 right now. The 2-s complement has the sign bit in the msb (most signfificant bit), so that won't work for bit-packing à la FOR. One possibility is to store the sign in the lsb (least significant bit). Storing signed integers this way is very unusual, there are no instruction that support this, as far as I know. The question now is: Can these lsb-signed-integers be encoded/decoded efficiently using SIMD instructions?
I think AVX-512 _mm_testn_epi32_mask
can be used to extract the lsb from each uint32, followed by a shift, then two mask_extract
of some sort? Quite convoluted.