faster Unique and AllUnique. Add algo_bench.cc - #3354
Conversation
jan-wassenberg
left a comment
There was a problem hiding this comment.
Very nice! Good point that CompressStore is safe within the vector-multiple loop; we only require CompressBlendedStore at the end. Nice speedup.
|
In CopyIf there are also CompressBlendedStore, it's possible to change it to CompressStore. But this works only if Some targets implements safe CompressBlendedStore, some - not. I think either we need to make all of them safe or allow to touch masked values. |
|
In x86_avx3-inl.h CompressStore for the partial vectors even the upper unused lanes of mask are used. Because of this CI fails on this PR. I added the guard for <16 bytes: And(mask, FirstN(d, HWY_MAX_LANES_D(D))) |
|
Thanks for fixing AVX3 partial CompressStore. CompressBlendedStore is documented to be implementable as LoadU+Blend+StoreU. I do not think we can guarantee anything beyond "won't SEGV if pointers are aligned". In msan builds (HWY_MEM_OPS_MIGHT_FAULT) even this isn't enough - msan would complain. We have SafeFillN and SafeCopyN which are safe regardless but slow. I intend to update those to use masking where native. Do you see any alternatives or improvements beyond that? |
|
So for num <= lanes it's possible to implement SafeCopyN = StoreN + LoadN. The comment above CopyIf doesnt guarantee that everything is OK if If this case isn't required to be safe, it is safe to use CompressStore instead of blend. If safety is necessary: StoreN(compressed, count_true), but this will impact performance on neon. Other variants I've come up with:
|
|
Yes, I think we should aim for STL compatibility and not necessarily require padding. Do you care enough about performance that it's worth providing a separate PaddedCopyIf (or a better name)? |
Previously, Unique used CompressBlendedStore, with the rationale that CompressStore couldn't be used because of in-place. But this is wrong, because always stores <= loads, so the next load can't be affected. Also I added 4x unroll, which hides latency.
For AllUnique I also added 4x unroll, so now AllFalse is performed once every 4N elements.
On apple m5:
All measurements
Before:Success.
Now:
For measurements I added algo_bench.cc. Currently it is only able to run AllUnique and Unique. In comments I describe how to add new.