Optimising C++ 2-D arrays

c++, gcc, linux, optimization, stl

Solution

If you're using GCC the compiler can analyze your matrix accesses and change the order in memory in certain cases. The magic compiler flag is defined as:

-fipa-matrix-reorg

Perform matrix flattening and transposing. Matrix flattening tries to replace a m-dimensional matrix with its equivalent n-dimensional matrix, where n < m. This reduces the level of indirection needed for accessing the elements of the matrix. The second optimization is matrix transposing that attemps to change the order of the matrix's dimensions in order to improve cache locality. Both optimizations need fwhole-program flag. Transposing is enabled only if profiling information is avaliable.

Note that this option is not enabled by -O2 or -O3. You have to pass it yourself.

Problem

I need a way to represent a 2-D array (a dense matrix) of doubles in C++, with absolute minimum accessing overhead. I've done some timing on various linux/unix machines and gcc versions. An STL vector of vectors, declared as: ``` vector<vector<double> > matrix(n,vector<double>(n)); ``` and accessed through `matrix[i][j]` is between 5% and 100% slower to access than an array declared as: ``` double *matrix = new double[n*n]; ``` accessed through an inlined index function `matrix[index(i,j)]`, where `index(i,j)` evaluates to i+n*j. Other ways of arranging a 2-D array without STL - an array of n pointers to the start of each row, or defining the whole thing on the stack as a constant size `matrix[n][n]` - run at almost exactly the same speed as the index function method. Recent GCC versions (> 4.0) seem to be able to compile the STL vector-of-vectors to nearly the same efficiency as the non-STL code when optimisations are turned on, but this is somewhat machine-dependent. I'd like to use STL if possible, but will have to choose the fastest solution. Does anyone have any experience in optimising STL with GCC?

Original source