c++ - The performance of multidimensional arrays and arrays of arrays -
i have thought , known multidimensional arrays indexing done once multiplication faster arrays of arrays indexing done 2 pointer dereferencing, due better locality , space saving.
i ran small test while ago, , result quite surprising. @ least callgrind profiler reported same function using array of arrays run faster.
i wonder whether should change definition of matrix class use array of arrays internally. class used virtually everywhere in simulation engine (? not sure how call..), , want find best way save few seconds.
test_matrix
has cost of 350 200 020
, test_array_array
has cost of 325 200 016
. code compiled -o3
clang++
. member functions inlined according profiler.
#include <iostream> #include <memory> template<class t> class basicarray : public std::unique_ptr<t[]> { public: basicarray() = default; basicarray(std::size_t); }; template<class t> basicarray<t>::basicarray(std::size_t size) : std::unique_ptr<t[]>(new t[size]) {} template<class t> class matrix : public basicarray<t> { public: matrix() = default; matrix(std::size_t, std::size_t); t &operator()(std::size_t, std::size_t) const; std::size_t get_index(std::size_t, std::size_t) const; std::size_t get_size(std::size_t) const; private: std::size_t sizes[2]; }; template<class t> matrix<t>::matrix(std::size_t i, std::size_t j) : basicarray<t>(i * j) , sizes {i, j} {} template<class t> t &matrix<t>::operator()(std::size_t i, std::size_t j) const { return (*this)[get_index(i, j)]; } template<class t> std::size_t matrix<t>::get_index(std::size_t i, std::size_t j) const { return * get_size(2) + j; } template<class t> std::size_t matrix<t>::get_size(std::size_t d) const { return sizes[d - 1]; } template<class t> class array : public basicarray<t> { public: array() = default; array(std::size_t); std::size_t get_size() const; private: std::size_t size; }; template<class t> array<t>::array(std::size_t size) : basicarray<t>(size) , size(size) {} template<class t> std::size_t array<t>::get_size() const { return size; } static void __attribute__((noinline)) test_matrix(const matrix<int> &m) { (std::size_t = 0; < m.get_size(1); ++i) { (std::size_t j = 0; j < m.get_size(2); ++j) { static_cast<volatile void>(m(i, j) = + j); } } } static void __attribute__((noinline)) test_array_array(const array<array<int>> &aa) { (std::size_t = 0; < aa.get_size(); ++i) { (std::size_t j = 0; j < aa[0].get_size(); ++j) { static_cast<volatile void>(aa[i][j] = + j); } } } int main() { constexpr int n = 1000; matrix<int> m(n, n); array<array<int>> aa(n); (std::size_t = 0; < aa.get_size(); ++i) { aa[i] = array<int>(n); } test_matrix(m); test_array_array(aa); }
Comments
Post a Comment