Машинное слово
- Другие названия
- machine word
- слово
- word
Машинное слово – единица данных, с которой процессор работает за одну операцию. Размер слова равен разрядности регистров общего назначения: 4 байта на 32-битных процессорах и 8 байт на 64-битных.
Размер слова
Указатель хранит адрес в памяти, а адрес обычно помещается в один регистр. Поэтому указатель занимает одно слово. Словами удобно мерить структуры из указателей и полей типа int: в словах их размер одинаков на всех платформах, а в байтах зависит от архитектуры процессора.
Машинное слово в Go
Спецификация Go задаёт размер uint нестрого – 32 или 64 бита; int занимает столько же, а uintptr вмещает любой указатель. Стандартный компилятор gc выбирает размер слова платформы, поэтому int, uint, uintptr и указатели занимают ровно одно слово: 4 байта на 32-битных платформах (386, arm) и 8 байт на 64-битных (amd64, arm64).
Из слов собраны хедеры встроенных типов, данные которых лежат в другом месте памяти:
- строка – два слова: указатель на массив байт и длина;
- слайс – три слова: указатель на массив, длина и капасити;
- интерфейсное значение – два слова: указатель на
itab(у пустого интерфейса – на тип) и указатель на данные.
Размер хедера не зависит от данных: строка из миллиона байт занимает те же два слова, что и пустая. Поэтому, когда строку, слайс или интерфейс передают в функцию, копируются только эти слова, а не сами данные.
Размер значения в байтах возвращает unsafe.Sizeof:
package machineword
import (
"fmt"
"unsafe"
)
func PrintSizes() {
var (
n int
p *int
s string
i any
slice []int
)
fmt.Printf("int: %d\n", unsafe.Sizeof(n))
fmt.Printf("*int: %d\n", unsafe.Sizeof(p))
fmt.Printf("string: %d\n", unsafe.Sizeof(s))
fmt.Printf("any: %d\n", unsafe.Sizeof(i))
fmt.Printf("[]int: %d\n", unsafe.Sizeof(slice))
}goНа 64-битной платформе (amd64, arm64) PrintSizes выведет:
int: 8
*int: 8
string: 16
any: 16
[]int: 24На 32-битной платформе (386, arm) каждое число вдвое меньше.
Подробнее о том, что хранят эти хедеры, – в статьях Строки в Go, Слайсы в Go и Интерфейсы в Go.