Add SVE implementation of remove - #6407
Conversation
|
Azure Pipelines: Successfully started running 1 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
|
/azp run |
|
Azure Pipelines: Successfully started running 2 pipeline(s). |
| }; | ||
|
|
||
| #if defined(_M_ARM64) // not ARM64EC, which lacks SVE | ||
| struct _SVE_8 { |
There was a problem hiding this comment.
We avoid macro-like names. _Sve_1 would be fine. Ditto below.
There was a problem hiding this comment.
Good point - done. It's just so drilled into me to use the "correct" (from an Arm branding perspective) capitalization of these things e.g. Neon not NEON and SVE not Sve 😄
There was a problem hiding this comment.
The NEON/Neon one is fun, because it used to be NEON and now it is Neon
| #if !defined(_M_ARM64) && !defined(_M_ARM64EC) | ||
| #if defined(_M_ARM64) // not ARM64EC, which lacks SVE | ||
| const size_t _Size_bytes = _Byte_length(_First, _Last); | ||
| bool _Use_sve = _Use_FEAT_SVE() && (_Size_bytes > 512 || _Sve_vl() > 16); |
There was a problem hiding this comment.
Please explain _Size_bytes > 512 here in __std_remove_copy_8 as opposed to _Size_bytes <= 96 in __std_remove_copy_1, and just if (_Use_FEAT_SVE()) in __std_remove_copy_2 and __std_remove_copy_4
There was a problem hiding this comment.
I've added comments for __std_remove_copy_8 and __std_remove_copy_1.
I hope the if (_Use_FEAT_SVE()) conditions are self explanatory - the SVE is unconditionally faster.
There was a problem hiding this comment.
Ah, I see, one SVE case competes against scalar, and the other against Neon, that makes sense then. thanks!
This PR adds an SVE implementation of
remove.Benchmark results (sizes/benchmarks for which the code path is unchanged are omitted):
Measured speedups on a Neoverse N2 Machine (Cobalt 100)
r<alg_type::std_fn, std::uint32_t>/7r<alg_type::std_fn, std::uint32_t>/15r<alg_type::std_fn, std::uint32_t>/31r<alg_type::std_fn, std::uint32_t>/47r<alg_type::std_fn, std::uint32_t>/63r<alg_type::std_fn, std::uint32_t>/95r<alg_type::std_fn, std::uint32_t>/127r<alg_type::std_fn, std::uint32_t>/255r<alg_type::std_fn, std::uint32_t>/511r<alg_type::std_fn, std::uint32_t>/1023r<alg_type::std_fn, std::uint32_t>/2047r<alg_type::std_fn, std::uint32_t>/4095r<alg_type::std_fn, std::uint32_t>/3230r<alg_type::std_fn, std::uint64_t>/7r<alg_type::std_fn, std::uint64_t>/15r<alg_type::std_fn, std::uint64_t>/31r<alg_type::std_fn, std::uint64_t>/47r<alg_type::std_fn, std::uint64_t>/63r<alg_type::std_fn, std::uint64_t>/95r<alg_type::std_fn, std::uint64_t>/127r<alg_type::std_fn, std::uint64_t>/255r<alg_type::std_fn, std::uint64_t>/511r<alg_type::std_fn, std::uint64_t>/1023r<alg_type::std_fn, std::uint64_t>/2047r<alg_type::std_fn, std::uint64_t>/4095r<alg_type::std_fn, std::uint64_t>/3230r<alg_type::rng, std::uint32_t>/7r<alg_type::rng, std::uint32_t>/15r<alg_type::rng, std::uint32_t>/31r<alg_type::rng, std::uint32_t>/47r<alg_type::rng, std::uint32_t>/63r<alg_type::rng, std::uint32_t>/95r<alg_type::rng, std::uint32_t>/127r<alg_type::rng, std::uint32_t>/255r<alg_type::rng, std::uint32_t>/511r<alg_type::rng, std::uint32_t>/1023r<alg_type::rng, std::uint32_t>/2047r<alg_type::rng, std::uint32_t>/4095r<alg_type::rng, std::uint32_t>/3230r<alg_type::rng, std::uint64_t>/7r<alg_type::rng, std::uint64_t>/15r<alg_type::rng, std::uint64_t>/31r<alg_type::rng, std::uint64_t>/47r<alg_type::rng, std::uint64_t>/63r<alg_type::rng, std::uint64_t>/95r<alg_type::rng, std::uint64_t>/127r<alg_type::rng, std::uint64_t>/255r<alg_type::rng, std::uint64_t>/511r<alg_type::rng, std::uint64_t>/1023r<alg_type::rng, std::uint64_t>/2047r<alg_type::rng, std::uint64_t>/4095r<alg_type::rng, std::uint64_t>/3230rc<alg_type::std_fn, std::uint8_t>/7rc<alg_type::std_fn, std::uint8_t>/15rc<alg_type::std_fn, std::uint8_t>/31rc<alg_type::std_fn, std::uint8_t>/47rc<alg_type::std_fn, std::uint8_t>/63rc<alg_type::std_fn, std::uint8_t>/95rc<alg_type::std_fn, std::uint16_t>/7rc<alg_type::std_fn, std::uint16_t>/15rc<alg_type::std_fn, std::uint16_t>/31rc<alg_type::std_fn, std::uint16_t>/47rc<alg_type::std_fn, std::uint16_t>/63rc<alg_type::std_fn, std::uint16_t>/95rc<alg_type::std_fn, std::uint16_t>/127rc<alg_type::std_fn, std::uint16_t>/255rc<alg_type::std_fn, std::uint16_t>/511rc<alg_type::std_fn, std::uint16_t>/1023rc<alg_type::std_fn, std::uint16_t>/2047rc<alg_type::std_fn, std::uint16_t>/4095rc<alg_type::std_fn, std::uint16_t>/3230rc<alg_type::std_fn, std::uint32_t>/7rc<alg_type::std_fn, std::uint32_t>/15rc<alg_type::std_fn, std::uint32_t>/31rc<alg_type::std_fn, std::uint32_t>/47rc<alg_type::std_fn, std::uint32_t>/63rc<alg_type::std_fn, std::uint32_t>/95rc<alg_type::std_fn, std::uint32_t>/127rc<alg_type::std_fn, std::uint32_t>/255rc<alg_type::std_fn, std::uint32_t>/511rc<alg_type::std_fn, std::uint32_t>/1023rc<alg_type::std_fn, std::uint32_t>/2047rc<alg_type::std_fn, std::uint32_t>/4095rc<alg_type::std_fn, std::uint32_t>/3230rc<alg_type::std_fn, std::uint64_t>/95rc<alg_type::std_fn, std::uint64_t>/127rc<alg_type::std_fn, std::uint64_t>/255rc<alg_type::std_fn, std::uint64_t>/511rc<alg_type::std_fn, std::uint64_t>/1023rc<alg_type::std_fn, std::uint64_t>/2047rc<alg_type::std_fn, std::uint64_t>/4095rc<alg_type::std_fn, std::uint64_t>/3230rc<alg_type::rng, std::uint8_t>/7rc<alg_type::rng, std::uint8_t>/15rc<alg_type::rng, std::uint8_t>/31rc<alg_type::rng, std::uint8_t>/47rc<alg_type::rng, std::uint8_t>/63rc<alg_type::rng, std::uint8_t>/95rc<alg_type::rng, std::uint16_t>/7rc<alg_type::rng, std::uint16_t>/15rc<alg_type::rng, std::uint16_t>/31rc<alg_type::rng, std::uint16_t>/47rc<alg_type::rng, std::uint16_t>/63rc<alg_type::rng, std::uint16_t>/95rc<alg_type::rng, std::uint16_t>/127rc<alg_type::rng, std::uint16_t>/255rc<alg_type::rng, std::uint16_t>/511rc<alg_type::rng, std::uint16_t>/1023rc<alg_type::rng, std::uint16_t>/2047rc<alg_type::rng, std::uint16_t>/4095rc<alg_type::rng, std::uint16_t>/3230rc<alg_type::rng, std::uint32_t>/7rc<alg_type::rng, std::uint32_t>/15rc<alg_type::rng, std::uint32_t>/31rc<alg_type::rng, std::uint32_t>/47rc<alg_type::rng, std::uint32_t>/63rc<alg_type::rng, std::uint32_t>/95rc<alg_type::rng, std::uint32_t>/127rc<alg_type::rng, std::uint32_t>/255rc<alg_type::rng, std::uint32_t>/511rc<alg_type::rng, std::uint32_t>/1023rc<alg_type::rng, std::uint32_t>/2047rc<alg_type::rng, std::uint32_t>/4095rc<alg_type::rng, std::uint32_t>/3230rc<alg_type::rng, std::uint64_t>/95rc<alg_type::rng, std::uint64_t>/127rc<alg_type::rng, std::uint64_t>/255rc<alg_type::rng, std::uint64_t>/511rc<alg_type::rng, std::uint64_t>/1023rc<alg_type::rng, std::uint64_t>/2047rc<alg_type::rng, std::uint64_t>/4095rc<alg_type::rng, std::uint64_t>/3230