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

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

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

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

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

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

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

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

    Для процессора Intel Xeon E5‑2696 v3 (архитектура Haswell‑EP) длина кэш‑линии (cache line size) составляет 64 байта.
    У Intel не было процессора, у которого размер кэш‑линии был бы 128 байт «по умолчанию» как стандартная величина для архитектуры.

    128 бит (16 байт) — размер операнда в старых SIMD‑инструкциях (SSE).
    256 бит (32 байта) — AVX.
    512 бит (64 байта) — AVX‑512. То есть AVX‑512 как раз «вписывается» ровно в одну кэш‑линию.

    128 байт иногда встречается не как размер кэш‑линии, а как:

    • размер блока в некоторых специализированных кэшах (например, eDRAM в Broadwell как кэш L4 на отдельном кристалле),
    • гранулярность в отдельных подсистемах или режимах работы, в определённых инструкциях может фигурировать 128-байтная гранулярность (например, при работе с SIMD-инструкциями или в специфических режимах доступа).