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

В подавляющем большинстве современных архитектур (x86/x64, ARM) минимальный адресуемый размер — это байт.

  • int (4 байта) должен быть выровнен по адресу, кратному 4.
  • long long (8 байт) должен быть выровнен по адресу, кратному 8.

Из-за этого младшие 2 бита (для 4-байтовых типов) или младшие 3 бита (для 8-байтовых типов) у корректного указателя всегда равны нулю.

Программисты и компиляторы этим активно пользуются — они прячут в эти “мертвые” биты служебную информацию (например, теги типов, цвет в красно-черных деревьях, флаги сборщика мусора), зануляя их перед разыменованием.

Можно ли сказать, что нижние несколько битов в указателе как правило не используются из-за того, что объекты в памяти выравниваются на размер линейки кеша процессора?

Кеш-линейка современного процессора имеет размер 64 байта (реже 128 байт). Это означает, что она выровнена по границе 64 байт, то есть младшие 6 бит адреса всегда нулевые.

  • Вежливый_ЛисOPM
    link
    fedilink
    Русский
    arrow-up
    1
    ·
    11 days ago

    Если два потока пишут в соседние переменные, которые попадают в одну и ту же 64‑байтную строку кэша, они будут «мешать» друг другу даже без явной гонки: кэш будет постоянно инвалидироваться между ядрами