Оптимизация расположения памяти экземпляров классов в C ++ - PullRequest
6 голосов
/ 03 апреля 2012

Обновление приложения с 32 до 64 бит увеличивает размер указателя и объем памяти объектов.

Я ищу способы максимально уменьшить объем памяти объектов. Для структур POD я выкидываю структуру памяти структуры, чтобы выяснить, как упаковать элементы и уменьшить заполнение компилятора.

Есть ли способ выяснить структуру памяти не-POD-объектов, таких как экземпляры классов? Как я могу добиться чего-то похожего на упаковку объектов класса?

Спасибо, Dan

Ответы [ 4 ]

4 голосов
/ 03 апреля 2012

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

Принудительная упаковка данных не очень хорошая идея для представлений в памяти.

1 голос
/ 03 апреля 2012

Я не знаю о конкретных данных не-POD-объектов (т.е. vtable), хотя я предполагаю, что это определяется размером указателя. В любом случае, вы можете управлять выравниванием элементов с помощью директивы компилятора #pragma pack, которая поддерживается GCC и Visual Studio .

Вы также можете прочитать параграф 7.18 на замечательном Руководстве по оптимизации Agner Fog C ++ :

Элементы данных класса или структуры хранятся последовательно в том порядке, в котором они объявляются всякий раз, когда создается экземпляр класса или структуры. Здесь нет снижение производительности за организацию данных в классы или структуры. Доступ к данным член класса или структуры объекта занимает не больше времени, чем доступ к простой переменной. Большинство компиляторов выравнивают элементы данных по округленным адресам для оптимизации доступа

0 голосов
/ 03 июня 2015

Относительно объектов, не относящихся к POD, я думаю, что вы должны прочитать больше о vTable, виртуальной функции, виртуальном наследовании, чтобы узнать, какие вещи определяют размер класса или объекта. Фактически, выравнивание класса, которое приводит к заполнению, выравнивание членов класса - только один из факторов, определяющих размер класса.

Здесь есть несколько связанных веб-сайтов, я думаю, что это может быть полезно для вас.

  1. Определить размер объекта класса: http://www.cprogramming.com/tutorial/size_of_class_object.html

  2. Структура памяти: http://www.phpcompiler.org/articles/virtualinheritance.html

И, если вы используете MVSC, вы можете сбросить всю структуру памяти всех классов в вашем решении с -d1reportAllClassLayout следующим образом:

cl -d1reportAllClassLayout main.cpp
0 голосов
/ 03 апреля 2012

Правило большого пальца: от наибольшего к наименьшему;это дает идеальное выравнивание, когда размеры элементов имеют степень двойки, в противном случае возможна ручная оптимизация.

Обратите внимание, что правильное выравнивание обычно важно для скорости, даже если процессор восстанавливается после нарушений.В то время как руки процессора x86 и (AFAIK) x64 внутренним образом выровняли доступ со вторым чтением, время, «потраченное» на чтение несоосности, обычно намного больше, чем время, сэкономленное из-за меньшего рабочего набора.Так что я бы "плотно упаковал" только когда вы запускаете сравнения на нескольких процессорах.

Для не POD вам нужно проверить sizeof(element).
(Если есть тонны объектов, я бы, вероятно, пошел с простым парсером, генерирующим C ++, чтобы вывести эти размеры)

В качестве альтернативы, PVS-Studio анализирует размеры структур и дает рекомендации по переупорядочению.Я еще мало их рассматривал, но вы можете использовать eval, чтобы выяснить, работает ли он на вас.

...