Подтвердить что ты не робот

Может ли __attribute __ ((упакован)) влиять на производительность программы?

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

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

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


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

Ответ 5

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

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

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

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