I have a function signature similiar to this
void Mutliply(const MatrixMN& a, const MatrixMN& b, MatrixMN& out);
Internally the matrix class has a float* data;
that represents the m x n
components. I'd like to tell the compiler that a
and b
do not alias the out matrix so it doesn't do a ton of load-stores.
How would I go about doing that? I know I could pass in pointers to the function signature and mark the pointers with __restrict
(in MSVC) but I'd like to keep the idiom of object passed by reference where the object contains pointers to memory.
I also know that __restrict
does not work on object references.
Depending on how the optimizer works, an assert(&in1 != &out && &in2 != &out)
at the top may do the trick. You could also get rid of the out parameter, and trust the optimizer to get rid of the superfluous copies (assuming it is a pure out parameter, of course). If the code is a candidate for inlining the compiler may see nothing is aliased on it's own. If restrict
really doesn't work on reference parameters, you can have an extra level to the function call, and pass all three to a second function that accepts pointers properly restricted. Hopefully, that one would get inlined for you.
Write a non-exported (file-static
, private
) multiplication function that takesfloat*
arguments, mark the arguments with restrict
. Make Multiply
call this function.
Since you seem to be comfortable with __restrict pointers, I would use what you know, but you can still wrap it and provide an interface using references:
void Multiply(const MatrixMN& a, const MatrixMN& b, MatrixMN& out) {
if (&a == &b || &a == &out || &b == &out) {
// indicate precondition violation however you like
assert(!"precondition violated");
abort(); // assert isn't always executed
}
else {
DoMultiply(&a, &b, &out);
}
}
void DoMultiply(MatrixMN const * __restrict a, MatrixMN const * __restrict b,
MatrixMN * __restrict out)
{
//...
}
Make the pointer version "non-public", such as placing it in a "details" namespace, giving it internal linkage (not applicable in this exact case), or giving it a special name. You could even use local variables instead of parameters and put the function body within the "else", but I find the above cleaner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With