2017-01-12 2 views
1

Класс C++, содержащий два вектора Eigen, имеет странный размер. У меня есть MWE моей проблемы здесь:Странный размер класса, содержащий собственные векторы

#include <iostream> 
#include "Eigen/Core" 

class test0 { 
    Eigen::Matrix<double,4,1> R; 
    Eigen::Matrix<double,4,1> T; 
}; 

class test1 { 
    Eigen::Matrix<double,4,1> R; 
    Eigen::Matrix<double,3,1> T; 
}; 

class test2 { 
    Eigen::Matrix<double,4,1> R; 
    Eigen::Matrix<double,2,1> T; 
}; 

class test3 { 
    Eigen::Matrix<double,7,1> T; 
}; 

class test4 { 
    Eigen::Matrix<double,3,1> T; 
}; 

int main(int argc, char *argv[]) 
{ 
    std::cout << sizeof(test0) << ", " << sizeof(test1) << ", " << sizeof(test2) << ", " << sizeof(test3) << ", " << sizeof(test4) << std::endl; 
    return 0; 
} 

Выход я получаю в моей системе (MacBook Pro, Xcode Clang ++ компилятор) является:

64, 64, 48, 56, 24

Класс «test1» имеет несколько причудливых дополнительных дополнений - я бы ожидал, что он будет иметь размер 56. Я не понимаю причину этого, особенно учитывая, что ни один из других классов не имеет дополнения. Может кто-нибудь объяснить, или это ошибка?

+0

«Я бы ожидал, что он будет иметь размер 56» - почему? –

+1

@latedeveloper, потому что он имеет 7 двухместных номеров. – zneak

+0

Я действительно имел в виду «почему, по вашему мнению, компилятор не может добавлять любые дополнения, которые ему нравятся, если только вы явно не контролируете его?» –

ответ

5

Это происходит из-за того, как реализована библиотека Eigen, и она не связана с трюками компилятора. В хранилище резервных копий для Eigen::Matrix<double, 4, 1> есть тег EIGEN_ALIGN_TO_BOUNDARY(16), в котором есть определения для компилятора, которые задают тип, который будет выровнен по 16-байтовой границе. Чтобы обеспечить это, компилятор должен добавить 8 байтов заполнения в конце структуры, так как в противном случае первое поле матрицы не будет выровнено по 16-байтовой границе, если у вас есть массив из test1.

Eigen просто не пытается наложить аналогичные требования к хранилищу Eigen::Matrix<double, 7, 1>.

Это происходит в Eigen/src/Core/DenseStorage.

+2

Вы можете использовать 'Matrix ' для локального отключения явного выравнивания и оплаты чуть менее эффективного векторизованного кода. – ggael

+0

Действительно. И Eigen :: Map по умолчанию использует неглавный формат. Поэтому я думаю, что моя проблема была в другом месте. – user664303

0

Требования к заполнению не обязательны для использования на языке, они на самом деле предусмотрены вашей архитектурой процессора. Ваш класс заполняется так, что он имеет ширину 64 байта. Конечно, вы можете переопределить это, но это делается так, что структуры сидят аккуратно в памяти и могут быть прочитаны эффективно, согласовываясь с линиями кэша.

В каких условиях структура дополняется, это сложный вопрос, но в целом «память дешевая, а циклы - нет». Современные компьютеры имеют массу памяти, и с тех пор, как увеличение производительности становится все труднее найти, когда мы приближаемся к границам меди, так что торговля некоторыми продуктами для производительности - это, как правило, хорошая идея.

Некоторое дополнительное чтение доступно here.


После обсуждения в комментариях стоит заметить, Не всякая оптимизация - хорошая идея, и даже тривиальные изменения в вашем коде могут иметь огромные последствия для некоторых оптимизаций. Если вам не нравится то, что производят ваши цепочки, и думаю, что вы можете сделать лучше, сделайте это! Возьмите несколько тестов, внесите изменения, а затем снова проверьте. По мере того как вы все это делаете, не тратьте время, потраченное на него, а затем спросите себя - было ли это хорошим использованием вами или вашим работодателем? :)

+0

Любое понимание того, почему test1 дополняется, а test3 и test4 нет? – user664303

+0

Я не верю, что выравнивание переменных-членов также объясняет существование отступов. Переменная T будет начинаться с 8-байтовой границы без заполнения, если R начинается с 8-байтовой границы (что необходимо). – user664303

+0

Как я уже прокомментировал этот вопрос, я считаю, что «это законно» является плохим объяснением неэффективности. – zneak

Смежные вопросы