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

Почему бы вам объединить два 32-битных целых числа в 64-битное целое число?

Недавно я увидел, как компилятор объединил два 32-битных целых числа, которые были значениями свойств класса и сохранили их как 64-битное целое число. Теперь мой вопрос: почему это делается? Какие преимущества существуют при объединении целых чисел?

например, если бы у нас были следующие свойства класса

class FooBar {
 int x = 1;
 int y = 100;
}

поэтому вместо

i32 = 00000001
i32 = 01100100

Получаем:

i64 = 0000000101100100

Зачем вам их комбинировать?

4b9b3361

Ответ 1

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

Компилятор инициализирует обе переменные одной 64-разрядной инструкцией (поскольку они разделяют последовательные адреса памяти). Переменные являются отдельными и будут доступны отдельно. Не требуется никакого переключения или маскировки.

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

Ответ 2

Я считаю, что вы наблюдаете оптимизацию. Инструкции Intel, такие как PADDSW, предполагают несколько упакованных операндов.

https://en.wikipedia.org/wiki/X86_instruction_listings

Есть также преимущества только при использовании 1 записи в кеше 64-битной архитектуры.

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

Раньше он был нормальным, чтобы выровнять все элементы структуры C на границе слова. Это единственный char, а int не будет упакован, а выровнен по размеру слова на машине. Таким образом, struct { char, int} будет иметь sizeof(..) из 8 байтов. Я предполагаю, что ситуация перевернулась?

Очень интересно.