Exposing @Vector types or not?

How do you feel about exposing a @Vector(4,f32) (for example) in the type signature of a function?

Is it considered bad practice, should I rather expose a [4]f32 and turn it into a vector internally to make use of SIMD instructions?

1 Like

I think it is better to expose this information. Knowing that it takes a vector, allows the user to make smarter decisions. Furthermore converting an array to a vector may have some cost to it, because it requires an unaligned load, since @alignOf([4]f32) is 4, whereas @alignOf(@Vector(4, f32)) is 16.

3 Likes

Thanks for your insight !

What happens when doing an unaligned load, if I may ask ?

In modern hardware the only difference appears to be that an unaligned memory access may cross cache line boundaries. This could reduce bandwidth, since you may need multiple cache lookups to load/store the vector. So if you use @Vector for storage outside this function, then it will always be aligned and you can achieve maximum memory bandwidth.

Now in most actual applications this probably won’t make a significant difference, and if you are lucky and your data doesn’t actually cross any cache line boundaries, then it won’t even make a difference.

3 Likes

Depends on the target too. Modern x86 has really small penalties for unaligned SIMD, usually just a single cycle on recent Zen architectures so long as you don’t incur any additional misses in your caches or TLBs or get an extra page fault.

Low power machines, however, might not even support unaligned loads and the compiler will load elements one by one. If you can align a vector, without much trouble, just do it.

3 Likes

Ultimately I would like to run it on a freestanding cortex M7 mcu, so I guess I’ll have to take it into consideration.

I think that chip doesn’t support SIMD anyway, so you are going to go one by one regardless.

Reading a bit further, it seems cortex m7 has some SIMD instructions but for 8bit or 16bit integers only. Thanks for pointing it out.

I personally just create named types when it starts to get ugly.

pub const Vec4 = @Vector(4, f32);
pub const Quat = @Vector(4, f32);

pub fn lerp(a: Vec4, b: Vec4, amount: f32) Vec4 {
...
}
1 Like