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()
}
 

>  
>
>>
>>> > 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.

Reply via email to