AcademySoftwareFoundation / AcademySoftwareFoundation/Imath

Improve structure element access idiom for vectorizing compilers

Open
#26 6 comments 2 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
488
Forks
161
Avg merge
1d 3h
Merged PRs (30d)
3

Description

I could do this myself if you want, but I don't want Owen and me to trip over each other, so let me just file this as an issue and he can decide when and how to do this.

Currently, our classes look like this:

template class Vec3
{
T x, y, z;
const T& operator [] (int i) const {
return (&x)[i];
}
}

This may seem ok for scalar code, but because the cast to a pointer in order to access the structures is technically UB, in all the compilers we have tested, when you do component access with `operator[]` *within a loop that you hope to autovectorize*, the compilers lose track of things in the implied conversion to raw pointer and that can cause the loop to fail to vectorize. This is because you are taking the address `&x` and then intentionally dereferencing past the end of `x`'s memory.

I propose the following change of idiom:

template class Vec3
{
union {
struct { T x, y, z; };
T arr_[3];
};

const T& operator [] (int i) const {
return arr_[i];
}
}

Note that direct access of `.x`, `.y`, `.z` will continue to work as always. Operator[] also still works. But there is no longer a cast directly from `&x` to a pointer that is used to access beyond x's extent.

Also, we should document that, just in case, `operator[]` should only be used if the array index is not known (like if you are looping over elements), but that for single element access where you know which one you want, `.x`, `.y`, and `.z` are preferred since we can make a stronger promise about the ability of the compiler to reason about autovectorization of expressions involving those.

Contributor guide

Open the contributing guide

Research direction

Locate the Vec3-style class definitions and their operator[] implementations, then inspect how component access is used in loops intended for autovectorization. Update the access idiom consistently and document when indexed access versus .x, .y, and .z is preferred; done means the affected classes retain direct component access while avoiding the described pointer-based access pattern.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-graphics, performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.