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.

Reply via email to