https://github.com/ClickHouse/ClickHouse/blob/a04b38db907b8e...
Obviously, SWAR should be slower (due to register size), but how slower?
https://github.com/ClickHouse/ClickHouse/blob/a04b38db907b8e...
Obviously, SWAR should be slower (due to register size), but how slower?
The gist of it is
lookup[hash(char)] == char
where 'lookup[hash(char)]' corresponds to _mm_shuffle_epi8 with a carefully crafted constant and input data, and '==' corresponds to _mm_cmpeq_epi8.The intrinsic c = _mm_shuffle_epi8(a, b) pretty much computes c[i] = b[a[i] & 0x0F], so if there are no collisions in a[i] & 0x0F, you can construct a special b so that
b[hash('@')] = '@'
b[hash('/')] = '/'
b[hash('?')] = '?'
b[hash('\\')] = '\\'
b[x] = 0x00 # otherwise
Unfortunately in this case, it doesn't work, since `/` and `?` have a collision, they both map to `0x0F`.If you would just search for say @, / and \, it would be possible, and shuffle + cmp is sufficient.
_mm256_srli_epi16 // by 1
_mm256_and_si256 // to mask off the high bit
_mm256_shuffle_epi8 // b[a[i] & 0x0F]
_mm256_cmpeq_epi8 // a[i] ==
This is still pretty good! If you end up needing more instructions to get map your chosen bytes to 16 unique low nibbles though, some other technique may pull ahead. See here for some techniques: http://0x80.pl/articles/simd-byte-lookup.htmlNote that the above article is a bit too conservative about the applicability of some of these techniques and does not end up telling you to do cmpeq(input, pshufb(constant, input)) even though this is what you want if all the bytes of interest are <128 (i.e. they are ascii characters) which is often true.
Here is a table from the Intel manual (bolded are the relevant compare instructions):
https://msdk.intel.com/en-us/library/cc286809.aspx
> SSE-4.2: Compare strings using dqa (32-bit mode), dqq (64-bit mode), dqu, dsx
> SSE-3: Compare strings using cmpsdx, cmpsd, scansigndx, scansignd
> SSE-2: Compare strings using pmaxsw, pand, pmin, pmins
> SSE-1: Compare strings using pandn, pavg, pandnpand, pandnpandn, pandn, pandnpandndivr, ...