You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Dec 22, 2021. It is now read-only.
Repository navigation
This repository was archived by the owner on Dec 22, 2021. It is now read-only.
@AndrewScheidecker mentioned in his review of #1 the possibility of including vectorized bit counting instructions to match the existing scalar instructions. They would have these signatures:
i8x16.clz(x: v128) -> v128
i16x8.clz(x: v128) -> v128
i32x4.clz(x: v128) -> v128
i64x2.clz(x: v128) -> v128
i8x16.ctz(x: v128) -> v128
i16x8.ctz(x: v128) -> v128
i32x4.ctz(x: v128) -> v128
i64x2.ctz(x: v128) -> v128
At least AArch64 has vectorized CLZ and RBIT instructions that could be used to implement this. But they could be quite impractical to emulate on other platforms.
Are these instructions widely available in SIMD instruction sets?
Are there plausible applications for these instructions?
MIPS SIMD implementation (MSA instructions) defines following bit count instructions:
NLZC.df - Vector element count of leading bits set to 0.
NLOC.df - Vector element count of leading bits set to 1.
PCNT.df - Vector element count of all bits set to 1.
df is vector element size and can be 8,16,32 or 64b
There is no CTZ or RBIT instructions, but we could emulate CTZ maybe with 4-5 different instructions (including PCNT.df).
Are there plausible applications for these instructions?
Those who added these (e.g. i32x16::count_ones) to Rust's portable packed SIMD module use them in the implementation of vectorized PRNGs and cared mostly about AVX-512 support.
We have a vectorized ambient occlusion example and benchmark that uses a pretty poor vectorized PRNG heavily, and going from a scalar to a vectorized PRNG had a huge performance impact. I don't recall exactly how big this was for this benchmark (I think it was in the ballpark of 1.5-2x for that example, it was one of the latest optimizations we did to catch up with ISPC on performance), but it shouldn't be too hard to switch the PRNG back to a scalar one and get some numbers.
SSE2+: CLZ/CTZ for 32/64 bit could use a floating point hack.
SSSE3: CLZ/CTZ for 8/16 bit could use PSHUFB.
CLZ/CTZ could be emulated on top of the popcnt.
Activity
simicicd commentedon Apr 21, 2017
MIPS SIMD implementation (MSA instructions) defines following bit count instructions:
NLZC.df - Vector element count of leading bits set to 0.
NLOC.df - Vector element count of leading bits set to 1.
PCNT.df - Vector element count of all bits set to 1.
df is vector element size and can be 8,16,32 or 64b
There is no CTZ or RBIT instructions, but we could emulate CTZ maybe with 4-5 different instructions (including PCNT.df).
billbudge commentedon Apr 21, 2017
ARM v7/v8 have:
Vector Count Leading Sign Bits VCLS
Vector Count Leading Zeros VCLZ
Vector Count Set Bits VCNT
stoklund commentedon May 25, 2017
Intel has
i32x4.clzandi64x2.clz, but only in AVX-512. I don't see vectorized versions of the other instructions.gnzlbg commentedon Mar 2, 2019
Those who added these (e.g.
i32x16::count_ones) to Rust's portable packed SIMD module use them in the implementation of vectorized PRNGs and cared mostly about AVX-512 support.We have a vectorized ambient occlusion example and benchmark that uses a pretty poor vectorized PRNG heavily, and going from a scalar to a vectorized PRNG had a huge performance impact. I don't recall exactly how big this was for this benchmark (I think it was in the ballpark of 1.5-2x for that example, it was one of the latest optimizations we did to catch up with ISPC on performance), but it shouldn't be too hard to switch the PRNG back to a scalar one and get some numbers.
aqrit commentedon Jan 16, 2021
SSE2+: CLZ/CTZ for 32/64 bit could use a floating point hack.
SSSE3: CLZ/CTZ for 8/16 bit could use PSHUFB.
CLZ/CTZ could be emulated on top of the popcnt.
SSE2 8-bit examples:
Count Leading (Redundant) Sign Bits could be emulated as: