Прежде всего, Eigen::Matrix<int,30,150>
по умолчанию будет выровнен до 16 байтов, что в 64-битных системах или с C ++ 17, скорее всего, будет работать правильно, но в противном случае вы можете столкнуться с некоторыми предостережениями . Простой способ обойти любые проблемы, связанные с выравниванием, - написать
typedef Eigen::Matrix<int,30,150, Eigen::DontAlign> HoughMatrix;
Теперь идиоматический c способ написать то, что вы хотите, будет написать
std::vector<HoughMatrix> hough_spaces(num_spaces, HoughMatrix::Zero());
Однако это будет результат в oop из memcpy
вызовов (по крайней мере для g cc и clang: https://godbolt.org/z/ULixBm).
В качестве альтернативы, вы можете создать вектор неинициализированных HoughMatrix
es и примените к ним std::memset
:
std::vector<HoughMatrix> hough_spaces(num_spaces);
std::memset(hough_spaces.data(), 0, num_spaces*sizeof(HoughMatrix));
Обратите внимание, что для того, чтобы для запуска Eigen без l oop через все элементы, необходимо, чтобы HoughMatrix
не выровнялся (как показано в начале ) или отключить утверждения выравнивания: https://godbolt.org/z/nDJqV5
Если вам на самом деле не нужна функциональность std::vector
(в основном это возможность копирования и изменения размера), вы можете просто выделить несколько использование памяти calloc
и free
после использования. Для обеспечения утечки это может быть заключено в std::unique_ptr
:
// unique_ptr with custom deallocator (use a typedef, if you need this more often):
std::unique_ptr<HoughMatrix[], void(&)(void*)> hough_spaces(static_cast<HoughMatrix*>(std::calloc(num_spaces, sizeof(HoughMatrix))), std::free);
if(!hough_spaces) throw std::bad_alloc(); // Useful, if you actually handle bad-allocs. If you ignore failed callocs, you'll likely segfault when accessing the data.
Clang и g cc оптимизирует это в одну пару calloc
/ free
: https://godbolt.org/z/m4rzRq
Совершенно другой подход - попытаться использовать трехмерный тензор вместо вектора матриц:
typedef Eigen::Tensor<int, 3> HoughSpace;
HoughSpace hough_spaces(num_spaces,30,150);
hough_spaces.setZero();
Просмотр сгенерированной сборки это выглядит полуоптимально, хотя даже с -O3 -DNDEBUG
.
В целом, обратите внимание, что сравнение всего, что связано с памятью, может вводить в заблуждение. Например, вызов calloc
может вернуться почти мгновенно, но на более низком уровне к нераспределенным страницам, что в действительности делает доступ к ним в первый раз более дорогим.