On Monday, February 6, 2017 at 7:43:33 AM UTC-5, T L wrote: > > > > On Monday, February 6, 2017 at 11:16:22 AM UTC, T L wrote: >> >> >> >> On Monday, February 6, 2017 at 6:43:04 PM UTC+8, T L wrote: >>> >>> >>> >>> On Monday, February 6, 2017 at 3:14:22 AM UTC+8, Ian Lance Taylor wrote: >>>> >>>> On Sun, Feb 5, 2017 at 10:52 AM, T L <tapi...@gmail.com> wrote: >>>> > Ian, thanks for the answers. >>>> > >>>> > But I still not very confirm on many points. >>>> > >>>> > Up to now, there are two places mention the alignments in Go. >>>> > >>>> > The first is in the end of Go spec: >>>> > >>>> > >>>> > Size and alignment guarantees >>>> > >>>> > For the numeric types, the following sizes are guaranteed: >>>> > >>>> > type size in bytes >>>> > >>>> > byte, uint8, int8 1 >>>> > uint16, int16 2 >>>> > uint32, int32, float32 4 >>>> > uint64, int64, float64, complex64 8 >>>> > complex128 16 >>>> > >>>> > The following minimal alignment properties are guaranteed: >>>> > >>>> > For a variable x of any type: unsafe.Alignof(x) is at least 1. >>>> > For a variable x of struct type: unsafe.Alignof(x) is the largest of >>>> all the >>>> > values unsafe.Alignof(x.f) for each field f of x, but at least 1. >>>> > For a variable x of array type: unsafe.Alignof(x) is the same as >>>> > unsafe.Alignof(x[0]), but at least 1. >>>> > >>>> > A struct or array type has size zero if it contains no fields (or >>>> elements, >>>> > respectively) that have a size greater than zero. Two distinct >>>> zero-size >>>> > variables may have the same address in memory. >>>> > >>>> > >>>> > The second is at the end of sync/atomic docs: >>>> > >>>> > >>>> > On x86-32, the 64-bit functions use instructions unavailable before >>>> the >>>> > Pentium MMX. >>>> > >>>> > On non-Linux ARM, the 64-bit functions use instructions unavailable >>>> before >>>> > the ARMv6k core. >>>> > >>>> > On both ARM and x86-32, it is the caller's responsibility to arrange >>>> for >>>> > 64-bit alignment of 64-bit words accessed atomically. The first word >>>> in a >>>> > global variable or in an allocated struct or slice can be relied upon >>>> to be >>>> > 64-bit aligned. >>>> > >>>> > >>>> > I feel the two are not enough to remove all my confusions. >>>> > >>>> > So could you help me remove the following confusions: >>>> > >>>> > >>>> > 1. What does the "allocated struct or slice" mean? >>>> > >>>> > >>>> > Currently, I think it means the structs or slices created by new, or >>>> the >>>> > structs or slices escape to heap. >>>> > >>>> > Is my understanding right? >>>> >>>> Those cases are "allocated struct or slice," yes. The phrase also >>>> includes variables defined with a struct or slice type. >>>> >>>> >>>> > 2. Are local 8-bytes variables 64bit aligned on 32bit OSes? >>>> > >>>> > >>>> > I found there are many usages of the 64bit functions of atomic >>>> package being >>>> > used on local 8-bytes variables in go source. >>>> > >>>> > So I think the answer is yes. Right? >>>> >>>> Yes. >>>> >>>> >>> I installed a 32bit VM and found that local int64 and [N]int64 variables >>> are not guaranteed to be 64bit aligned. >>> But the magic is, if the local int64 variables are passed to atomic >>> 64bit functions, then they become 64bit aligned for sure. >>> Quite magic. >>> >>> It looks when local int64 variables are escaped to heap if their >>> addresses are passed to atomic 64bit functions. >>> And it looks 64bit words allocated on heap are always 64bit aligned, >>> even on 32bit OSes. >>> >>> >>> >> >> The same is for local structs which first field is a 64bit word. Such >> local structs are also not guaranteed to be 64bit aligned. >> But if the addresses of the 64bit word fields are passed to atomic 64bit >> functions, then the local structs will escape to heap, >> so the local structs become 64bit aligned on heap. >> >> > The same for local slices. > > The full code: > > // go version go1.7.5 linux/386 > > package main > > import ( > "sync/atomic" > ) > > func fa() { > println("========== fa") > var b bool > var arr [5]int64 > println(&b, &arr) // 0x1843bf73 0x1843bf74 > } > > func fa2() { > println("========== fa2") > var b bool > var arr [5]int64 > println(&b, &arr) // 0x1843bf57 0x184120f0 > atomic.LoadInt64(&arr[0]) > } > > func fb() { > println("========== fb") > var b bool > var x = new(int64) > println(&b, &x) // 0x1843bf73 0x1843bf74 > } > > func fb2() { > println("========== fb2") > var b bool > var x int64 > println(&b, &x) // 0x1843bf57 0x184120f0 > atomic.LoadInt64(&x) > } > > func fc() { > println("========== fc") > var b bool > var slc = make([]int64, 1) > println(&b, &slc[0]) // 0x1843bf5b 0x1843bf5c > } > > func fc2() { > println("========== fc2") > var b bool > var slc = make([]int64, 1) > println(&b, &slc[0]) // 0x1843bf37 0x1840e0e0 > atomic.LoadInt64(&slc[0]) > } > > func fd() { > type T struct { > x int64 > } > println("========== fd") > var b bool > var t T > println(&b, &t.x) // 0x1843bf33 0x1843bf34 > } > > func fd2() { > type T struct { > x int64 > } > println("========== fd2") > var b bool > var t T > println(&b, &t.x) // 0x1843bf37 0x1840e0f0 > atomic.LoadInt64(&t.x) > } > > func fd3() { > type T struct { > x int64 > } > println("========== fd3") > var b bool > var t = new(T) > println(&b, &t.x) // 0x1843bf33 0x1843bf34 > } > > func main() { > fa() > fa2() > > fb() > fb2() > > fc() > fc2() > > fd() > fd2() > fd3() > } > >
It looks the latest gc (1.10) always makes 64-bit words aligned on i386 OSes. Can any Go team member confirm this? > >> >>> >>>> > 3. Are expvar.Int and expvar.Float safe to be embedded in other >>>> structs on >>>> > 32bit OSes? >>>> > >>>> > >>>> > I think the answer is no. Is my opinion right? >>>> >>>> You could embed them as the first field of a struct (if you were then >>>> careful to not embed that struct, (except as the first field)). >>>> >>>> It would not be portable to embed them as anything other than the first >>>> field. >>>> >>>> I think this is problematic, and it would be nice to figure out a way >>>> to fix it. >>>> >>>> Ian >>>> >>> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.