Подсчет накладных расходов из-за упаковки в C (gcc / g ++) - PullRequest
3 голосов
/ 12 июля 2011

Я хотел бы подсчитать / суммировать накладные расходы в объектном файле из-за упаковки (и, в идеале, gcc минимизировать это для меня).

Например, рассмотрим следующую структуру (32-битная)x86, gcc):

struct a { 
    uint8_t a_char;
    uint32_t an_integer
    uint8_t another_letter;
};

В то время как фактические данные занимают всего 6 байтов, структура занимает 12 байтов в памяти, потому что после обоих символов следуют 3 байта заполнения.Переупорядочив структуру следующим образом:

struct b { 
    uint32_t an_integer
    uint8_t a_char;
    uint8_t another_letter;
};

Структура будет иметь только sizeof (struct b) == 8 (все еще 4 байта служебных данных).

(1) В идеале, I 'Мне бы хотелось, чтобы gcc переставил struct a в struct b и сэкономил мне место, но моя версия (4.2), похоже, не делает этого ни для какого уровня оптимизации.

(2) В качестве альтернативы, учитывая struct a, я бы хотел (автоматически) получить либо число 6 (общая сумма накладных расходов), либо 4 (минимальная сумма накладных расходов, если члены упорядочены «в идеале»).Цель этого состоит в том, чтобы определить, стоит ли переупорядочение структур вручную времени (вероятно, нет).

Есть ли способ для gcc сделать (1), и есть ли инструмент, который будет работать (2)?Наиболее близкая вещь, которую я могу придумать для (1), это #pragma pack(1), но (я предполагаю) это будет иметь серьезные последствия для производительности, поскольку большинство / все обращения к памяти будут выровнены.Что касается (2), я думаю, что Perl-скрипт, разбирающий символы отладки, мог бы сделать это, но я недостаточно знаком с DWARF, чтобы знать наверняка.

Ответы [ 3 ]

8 голосов
/ 12 июля 2011

Для # 1 причина, по которой это не сделано, заключается в том, что стандарты C и C ++ запрещают переупорядочение элементов структуры.

Да, структура упаковки обычно снижает производительность. И, как упоминалось в комментарии, в некоторых случаях на архитектурах, отличных от x86, вы можете получить SIGBUS, если попытаетесь работать с участником.

Для # 2, да, сценарий Perl может сделать это. Вместо анализа информации DWARF вы можете попробовать сканировать исходный код на наличие структурных определений и, возможно, сгенерировать несколько небольших тестовых программ для проверки sizeof () структур и членов и т. Д.

3 голосов
/ 12 июля 2011

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

0 голосов
/ 12 июля 2011

Это не всегда может быть сделано, проблема в том, что доступ к невыровненной памяти не разрешен на всех архитектурах.Это также упрощает некоторый код для компилятора, позволяя оптимизировать определенные обращения к самой памяти.Кроме того, реорганизация структур, вероятно, не стоит вашего времени, поскольку 4-8 байтов служебной информации на структуру не имеют большого значения, если вы не используете ОЧЕНЬ чувствительное к памяти программное обеспечение.Что касается вашего вопроса, я не уверен, есть ли способ, но я уверен, что если кто-то знает, они сообщат вам (возможно, это делает gcc-4.6 с наивысшим флагом оптимизации?)

...