Действительно ли порядок членов объектов класса оказывает какое-либо влияние на производительность?

Может ли порядок членов в двоичной архитектуре объектов класса каким-то образом повлиять на производительность приложений, которые используют этот класс? и мне интересно, как решить порядок членов 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