Я много читал о том, как важно выравнивание значений в памяти, потому что доступ к невыровненным адресам может либо замедлить работу, либо просто не работать вообще, в зависимости от архитектуры ЦП (одна ссылка https://syslog.ravelin.com/go-and-memory-layout-6ef30c730d51). Но потом я заметил, что при создании простой строки в Go она часто хранит строковое значение по неверно выровненному адресу.
Это можно увидеть, выполнив следующий код:
package main
import (
"fmt"
"unsafe"
"reflect"
)
func main() {
testString:= "testString"
fmt.Println(fmt.Sprintf("Data is at address %d", ((*reflect.StringHeader)(unsafe.Pointer(&testString))).Data))
}
При запуске на https://play.golang.org/p/d1eX0nP3AgV я получаю:
Data is at address 1140305
1140305
явно не делится на 4
или 8
.
Может кто-нибудь объясните, почему Go хранит это значение по смещенному адресу, пожалуйста? Не лучше ли использовать выровненный? Это просто, чтобы не тратить пространство, полагаясь на то, что современные процессоры могут справиться с этим. Или это потому, что уровень виртуальной памяти абстрагирует адрес физической памяти и фактически физический адрес правильно выровнен?