Действительно ли порядок членов объектов класса оказывает какое-либо влияние на производительность?
Может ли порядок членов в двоичной архитектуре объектов класса каким-то образом повлиять на производительность приложений, которые используют этот класс? и мне интересно, как решить порядок членов POD, если да, так как программист определяет порядок участников через порядок их объявлений
Ответы
Ответ 1
Совершенно верно. С++ гарантирует, что порядок объектов в памяти будет таким же, как и порядок объявления, если не будет выбран квалификатор доступа.
Объекты, которые непосредственно смежны, с большей вероятностью будут находиться в одной и той же линии кэширования, поэтому один доступ к памяти будет извлекать их оба (или сбросить оба из кеша). Эффективность кеша также может быть улучшена, поскольку доля полезных данных внутри него может быть выше. Проще говоря, пространственная локальность в вашем коде преобразуется в пространственную локальность для производительности.
Кроме того, как отмечает Джерри в комментариях, порядок может влиять на количество отступов. Сортируйте элементы, уменьшая размер, а также уменьшая выравнивание (обычно рассматривайте массив как только один элемент его типа, а член-структуру - его наиболее выровненный член). Ненужное заполнение может увеличить общий размер структуры, что приведет к увеличению трафика памяти.
С++ 03 §9/12:
Нестатические элементы данных (неединичный) класс, объявленный без промежуточный спецификатор доступа выделяется так, что последующие члены более высокие адреса в классе объект. Порядок распределения нестатические элементы данных, разделенные спецификатор доступа не указан (11.1). Выравнивание реализации требования могут привести к двум смежные участники не будут распределены сразу после друг друга; так что требования к пространству для управления виртуальные функции (10.3) и виртуальные базовые классы (10.1).
Ответ 2
Абсолютно согласен с Potatoswatter. Однако необходимо добавить еще один момент о строках кэша CPU.
Если ваше приложение многопоточно и разные потоки читают/записывают членов вашей структуры - очень важно убедиться, что эти члены не в пределах одной и той же строки кэша.
Дело в том, что всякий раз, когда поток изменяет адрес памяти, который кэшируется в другом процессоре, этот CPU немедленно лишает законной силы строку кэша, содержащую этот адрес. Таким образом, неправильный порядок членов может привести к необоснованной недействительности кеша и ухудшению производительности.
Ответ 3
В дополнение к производительности исполнения, описанному в ответах на кеш-линию, я думаю, следует также учитывать производительность памяти, то есть размер объекта класса.
Из-за padding размер объекта класса зависит от порядка объявления переменной-члена.
Следующее объявление, вероятно, займет 12 байт
class foo {
char c1;
int i;
char c2;
}
Однако при простом переупорядочении порядка объявления участника, возможно, потребуется 8 байт
class bar {
int i;
char c1;
char c2;
}
В машинах, выровненных с 4-байтовыми словами:
sizeof( foo ) = 12
но
sizeof( bar ) = 8