Может ли __attribute __ ((упакованный)) влиять на производительность программы? - PullRequest
12 голосов
/ 11 августа 2010

У меня есть структура с именем log, в которой 13 символов. выполнив sizeof (log), я вижу, что размер не 13, а 16. Я могу использовать __attribute __ ((упакованный)), чтобы получить фактический размер 13, но мне интересно, повлияет ли это на производительность программы. Это структура, которая используется довольно часто.

Я хотел бы иметь возможность прочитать размер структуры (13, а не 16). Я мог бы использовать макрос, но если эта структура когда-либо изменяется, то есть поля добавляются или удаляются, я бы хотел, чтобы новый размер обновлялся без изменения макроса, потому что я думаю, что это подвержено ошибкам. Есть предложения?

Ответы [ 5 ]

15 голосов
/ 11 августа 2010

Да, это повлияет на производительность программы. Добавление отступов означает, что компилятор может использовать целочисленные инструкции загрузки для чтения данных из памяти. Без дополнения компилятор должен загружать вещи отдельно и выполнять сдвиг битов, чтобы получить все значение. (Даже если это x86, и это делается аппаратно, это все равно нужно сделать).

Примите во внимание следующее: почему компиляторы вставляют случайное, неиспользуемое пространство, если это происходит не по причинам производительности?

6 голосов
/ 11 августа 2010

Не используйте __attribute__((packed)).Если ваша структура данных находится в памяти, позвольте ей занимать свой естественный размер, как определено компилятором.Если это для чтения / записи на / с диска, пишите функции сериализации и десериализации;не просто хранить двоичные структуры процессора на диске.«Упакованные» структуры действительно имеют нет законного использования (или очень мало; см. Комментарии к этому ответу для возможных противоречивых точек зрения).

5 голосов
/ 11 августа 2010

Да, это может повлиять на производительность.Как это зависит от того, что это такое и как вы его используете.

Не выровненная переменная может охватывать две строки кэша.Например, если у вас есть 64-байтовые строки кэша и вы читаете 4-байтовую переменную из массива 13-байтовых структур, существует вероятность 3 к 64 (4,6%), что она будет распределена по двум строкам.Штраф за дополнительный доступ к кешу довольно мал.Если бы все, что делала ваша программа, было рассчитано на эту одну переменную, 4,6% было бы верхней границей снижения производительности.Если регистрация составляет 20% рабочей нагрузки программы, а чтение / запись в эту структуру составляет 50% регистрации, то вы уже находитесь на небольшой доле процента.

С другой стороны, предполагая, чтожурнал должен быть сохранен, сокращение каждой записи на 3 байта экономит вам 19%, что приводит к большому объему памяти или дискового пространства.Основная память и особенно диск медленные, поэтому вам, вероятно, будет лучше упаковать журнал, чтобы уменьшить его размер.


Что касается чтения размера структуры, не беспокоясь об изменении структуры, используйте sizeof.Как бы вы ни хотели использовать числовые константы, будь то const int, enum или #define, просто добавьте sizeof.

5 голосов
/ 11 августа 2010

Да, это может повлиять на производительность. В этом случае, если вы выделите массив таких структур с атрибутом ((packed)), большинство из них должны остаться невыровненными (тогда как если вы используете упаковку по умолчанию, все они могут быть выровнены по 16-байтовым границам). Копирование таких структур может быть быстрее, если они выровнены.

0 голосов
/ 21 ноября 2013

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

Если вы создаете гигантские массивы, экономия пространства от упаковки может означать разницу между подгонкой и не подгонкой кеша. Или ваши данные могут уже вписаться в ваш кеш, и в этом случае это не будет иметь никакого значения. Если вы выделяете большое количество структур в ассоциативном контейнере STL, который выделяет хранилище для вашей структуры с operator new, это может не иметь никакого значения --- operator new может округлить ваше хранилище до того, что выровнено в любом случае.

Если большинство ваших структур находится в стеке, дополнительное хранилище может быть уже оптимизировано.

Для изменения, которое так просто проверить, я предлагаю построить временную установку, а затем попробовать все в обоих направлениях. Для дальнейшей оптимизации я предлагаю использовать профилировщик, чтобы выявить ваши узкие места и перейти оттуда.

...