By: Jan Wassenberg (jan.wassenberg.delete@this.gmail.com), May 21, 2022 10:45 pm
Room: Moderated Discussions
Charlie Burnes (charlie.burnes.delete@this.no-spam.com) on May 21, 2022 7:48 am wrote:
> Could you please explain D, d and Simd in a little more detail? I saw that Lanes(d) is the actual
> number of SIMD lanes used but I don’t understand how and why d determines that.
Sure! BTW please feel to raise Github issues for any questions you or others might have.
D is shorthand for Simd and d is an lvalue of type D. Simd is a zero-sized struct used only to select overloads. For example, we have two overloads:
HWY_API Vec256 Zero(Full256 /* tag */)
HWY_API Vec512 Zero(Full512 /* tag */)
Full256 is simply an alias for Simd.
For platforms with fixed-size vectors, N exactly corresponds to the vector size as returned by Lanes(). Lanes(d) simply returns the N deduced from d (recall that its type is Simd).
(It could have been constexpr but that would invite code that breaks on platforms where Lanes is not constexpr.)
> The Highway API synopsis/quick reference uses the notation N, D and d:
> What do you mean by “governs (but is not necessarily identical to)”?
For example, on SVE Lanes() instead maps to svcnt. Now the "governs" comes into play: Lanes() is a function of the hardware lane count, N as a user-specified upper bound, or the shift count which on SVE can be a fraction such as 1/4 of the hardware lane count.
For example, CappedTag has N=2 which is smaller than the hardware lane count but the ops behave as if you actually had a 64-bit vector.
But CappedTag will have vec_bytes/4 lanes, which SVE guarantees is at most 64. So here the N can influence, but is not identical to what Lanes returns. Does that make sense?
> Could you please explain D, d and Simd in a little more detail? I saw that Lanes(d) is the actual
> number of SIMD lanes used but I don’t understand how and why d determines that.
Sure! BTW please feel to raise Github issues for any questions you or others might have.
D is shorthand for Simd and d is an lvalue of type D. Simd is a zero-sized struct used only to select overloads. For example, we have two overloads:
HWY_API Vec256 Zero(Full256 /* tag */)
HWY_API Vec512 Zero(Full512 /* tag */)
Full256 is simply an alias for Simd.
For platforms with fixed-size vectors, N exactly corresponds to the vector size as returned by Lanes(). Lanes(d) simply returns the N deduced from d (recall that its type is Simd).
(It could have been constexpr but that would invite code that breaks on platforms where Lanes is not constexpr.)
> The Highway API synopsis/quick reference uses the notation N, D and d:
> What do you mean by “governs (but is not necessarily identical to)”?
For example, on SVE Lanes() instead maps to svcnt. Now the "governs" comes into play: Lanes() is a function of the hardware lane count, N as a user-specified upper bound, or the shift count which on SVE can be a fraction such as 1/4 of the hardware lane count.
For example, CappedTag has N=2 which is smaller than the hardware lane count but the ops behave as if you actually had a 64-bit vector.
But CappedTag will have vec_bytes/4 lanes, which SVE guarantees is at most 64. So here the N can influence, but is not identical to what Lanes returns. Does that make sense?