I'm using Armadillo to do very intensive matrix multiplications with side lengths $2^n$, where $n$ can be up to 20 or even more. I'm using Armadillo with OpenBLAS for matrix multiplication, which seems to be doing a very good job in parallel cores, except that I have a problem with the formalism of multiplication in Armadillo for super optimization of performance.
Say that I have a loop in the following form:
arma::cx_mat stateMatrix, evolutionMatrix; //armadillo complex matrix type
for(double t = t0; t < t1; t += 1/sampleRate)
{
...
stateMatrix = evolutionMatrix*stateMatrix;
...
}
In fundamental C++, I find the problem here is that C++ will allocate a new object of cx_mat
to store evolutionMatrix*stateMatrix
, and then copy the new object to stateMatrix
with operator=()
. This is very, very inefficient. It's well known that returning complex classes of large data types is a bad idea, right?
The way I see this going way more efficient is with a function doing the multiplication in the form:
void multiply(const cx_mat& mat1, const cx_mat& mat2, cx_mat& output)
{
... //multiplication of mat1 and mat2 and then store it in output
}
This way, One doesn't have to copy huge objects with return value, and the output doesn't have to be reallocated with every multiplication.
The Question: How can I find a compromise, in which I can use Armadillo for multiplication with its nice interface of BLAS, and do this efficiently without having to recreate matrix objects and copy them with each operation?
Isn't this an implementation problem in Armadillo?
stateMatrix = evolutionMatrix*stateMatrix
won't do any copying whatsoever. Instead, Armadillo does a fancy memory pointer change. New memory for the result will still be allocated (there is no way around that), but instead of copying, thestateMatrix
matrix will simply use the new memory and discard the old memory. $\endgroup$