Разве размер vptr на 64-битных компьютерах ** должен ** быть 64-битным?

Мне любопытно, почему размер vptr занимает 64 бита на 64-битных машинах и действительно ли это требуется в C++.

Все, что нужно сделать vptr, это указать на vtables, и поскольку vtables не может занимать слишком много памяти и может быть сгруппирован вместе, 32 бита должно быть более чем достаточно для их решения.

Сколько классов у вас в программе? 1000? 10000? Сколько виртуальных функций у них в среднем? Может быть 100? Если компилятор + компоновщик разместит все vtables последовательно, они не могут занять более нескольких МБ. Адресация конкретной таблицы с 32-битным индексом в "массив всех таблиц" должна работать.

Я даже говорю об этом из-за определенных небольших классов с виртуальными функциями; иногда я вижу огромные массивы объектов класса всего с двумя словами + vptr, и этот 64-битный vptr оказывает значительное влияние на использование памяти.

2 ответа

Нет, он не должен быть 64-битным. Но есть несколько причин, по которым это так:

  • Существует вероятность того, что первый член класса нуждается в 64-битном выравнивании, поэтому в этом случае нет никакой выгоды
  • Обычно vptrs не занимают значительную память
  • И самый сильный аргумент: если vptr будет 32-битным индексом, то все вызовы виртуальных функций будут медленнее (из-за дополнительной ссылки на память) и будут генерировать больший код. Это просто не стоит того.

Обратите внимание, что есть модель памяти (ILP32, -mx32 switch для gcc), который редко используется, где указатели 32-битные, но могут использоваться 64-битные регистры.

Микрооптимизация памяти сейчас не в фокусе. Например, компилятор может свободно переупорядочивать элементы по спецификаторам доступа (так что заполнение может быть уменьшено), но ни один из известных мне компиляторов не делает этого.

Ваше подозрение верно, это действительно разрешено C++. 16 битов не могут быть реалистичными, хотя. И даже если бы все vtables были больше чем 4 ГБ, они обычно не были бы большими 4 миллиардами записей. Типичная стабильная запись составляет 64 бита, поэтому 4 миллиарда записей занимают 32 ГБ.

Другие вопросы по тегам