[go-nuts] Re: A Question about `unsafe.Slice`

2022-02-05 Thread rmfr
I found the comments of `findObject` in the runtime source:

```go
// findObject returns the base address for the heap object **containing**
// the address p, the object's span, and the index of the object in s.
// If p does not point into a heap object, it returns base == 0.
//
// If p points is an invalid heap pointer and debug.invalidptr != 0,
// findObject panics.
//
// refBase and refOff optionally give the base address of the object
// in which the pointer p was found and the byte offset at which it
// was found. These are used for error reporting.
//
// It is nosplit so it is safe for p to be a pointer to the current 
goroutine's stack.
// Since p is a uintptr, it would not be adjusted if the stack were to move.
//go:nosplit
func findObject(p, refBase, refOff uintptr) (base uintptr, s *mspan, 
objIndex uintptr)
```

On Sunday, February 6, 2022 at 10:33:35 AM UTC+8 rmfr wrote:

> It suddenly occurred to me that it was very like `re-slice` —— as long as 
> part of the underlying array is referenced, the whole underlying array is 
> never gc-ed. I guess there is a method in gc which could locate the whole 
> underlying array as long as one address inside the array's address interval 
> was provided? So now I tend to believe that `Element1` is correct too, and 
> the `underlyBuf` filed in `Element2` is redundant and is not quite 
> necessary, am I correct?
>
> On Sunday, February 6, 2022 at 10:08:06 AM UTC+8 rmfr wrote:
>
>> Please take a look at the following code:
>>
>> ```go
>> package main
>>
>> import (
>> "fmt"
>> "runtime"
>> "unsafe"
>> )
>>
>> func assert(b bool) {
>> if b {
>> } else {
>> panic("unexpected")
>> }
>> }
>>
>> type Elementer interface {
>> GetInt64Slice() []int64
>> GetByteSlice() []byte
>> String() string
>> }
>>
>> type Element1 struct {
>> int64s []int64
>> bs []byte
>> }
>>
>> func newElement1(int64Sz, bsSz int) *Element1 {
>> assert(int64Sz > 0 && bsSz > 0)
>> len0 := int64Sz * 8
>> len1 := bsSz
>> buf := make([]byte, len0+len1)
>> for i := range buf {
>> buf[i] = byte(i)
>> }
>> e := {
>> int64s: unsafe.Slice((*int64)(unsafe.Pointer([0])), int64Sz),
>> bs: unsafe.Slice((*byte)([len0]), bsSz),
>> }
>> return e
>> }
>>
>> func (e *Element1) GetInt64Slice() []int64 {
>> return e.int64s
>> }
>>
>> func (e *Element1) GetByteSlice() []byte {
>> return e.bs
>> }
>>
>> func (e *Element1) String() string {
>> return fmt.Sprintf("Element1:[% x % x]", e.GetInt64Slice(), 
>> e.GetByteSlice())
>> }
>>
>> type Element2 struct {
>> underlyBuf []byte  // <- is this field needed?
>> int64s []int64
>> bs []byte
>> }
>>
>> func newElement2(int64Sz, bsSz int) *Element2 {
>> assert(int64Sz > 0 && bsSz > 0)
>> len0 := int64Sz * 8
>> len1 := bsSz
>> buf := make([]byte, len0+len1)
>> for i := range buf {
>> buf[i] = byte(i)
>> }
>> e := {
>> underlyBuf: buf,   // <-
>> int64s: unsafe.Slice((*int64)(unsafe.Pointer([0])), 
>> int64Sz),
>> bs: unsafe.Slice((*byte)([len0]), bsSz),
>> }
>> return e
>> }
>>
>> func (e *Element2) GetInt64Slice() []int64 {
>> runtime.KeepAlive(e.underlyBuf)
>> return e.int64s
>> }
>>
>> func (e *Element2) GetByteSlice() []byte {
>> runtime.KeepAlive(e.underlyBuf)
>> return e.bs
>> }
>>
>> func (e *Element2) String() string {
>> runtime.KeepAlive(e.underlyBuf)
>> return fmt.Sprintf("Element2:[% x % x]", e.GetInt64Slice(), 
>> e.GetByteSlice())
>> }
>>
>> func main() {
>> var e Elementer
>> fmt.Println("print with host endian:")
>> e = newElement1(2, 4)
>> fmt.Println("hi", e)
>> e = newElement2(2, 4)
>> fmt.Println("hi", e)
>> }
>> ```
>>
>> And which yields:
>>
>> ```
>> hi Element1:[[ 706050403020100  f0e0d0c0b0a0908] 10 11 12 13]
>> hi Element2:[[ 706050403020100  f0e0d0c0b0a0908] 10 11 12 13]
>> ```
>>
>> I'm not sure whether the `underlyBuf` filed in `Element2` is needed or 
>> not. When I'm reading the doc from `
>> https://pkg.go.dev/reflect#SliceHea

[go-nuts] Re: A Question about `unsafe.Slice`

2022-02-05 Thread rmfr
It suddenly occurred to me that it was very like `re-slice` —— as long as 
part of the underlying array is referenced, the whole underlying array is 
never gc-ed. I guess there is a method in gc which could locate the whole 
underlying array as long as one address inside the array's address interval 
was provided? So now I tend to believe that `Element1` is correct too, and 
the `underlyBuf` filed in `Element2` is redundant and is not quite 
necessary, am I correct?

On Sunday, February 6, 2022 at 10:08:06 AM UTC+8 rmfr wrote:

> Please take a look at the following code:
>
> ```go
> package main
>
> import (
> "fmt"
> "runtime"
> "unsafe"
> )
>
> func assert(b bool) {
> if b {
> } else {
> panic("unexpected")
> }
> }
>
> type Elementer interface {
> GetInt64Slice() []int64
> GetByteSlice() []byte
> String() string
> }
>
> type Element1 struct {
> int64s []int64
> bs []byte
> }
>
> func newElement1(int64Sz, bsSz int) *Element1 {
> assert(int64Sz > 0 && bsSz > 0)
> len0 := int64Sz * 8
> len1 := bsSz
> buf := make([]byte, len0+len1)
> for i := range buf {
> buf[i] = byte(i)
> }
> e := {
> int64s: unsafe.Slice((*int64)(unsafe.Pointer([0])), int64Sz),
> bs: unsafe.Slice((*byte)([len0]), bsSz),
> }
> return e
> }
>
> func (e *Element1) GetInt64Slice() []int64 {
> return e.int64s
> }
>
> func (e *Element1) GetByteSlice() []byte {
> return e.bs
> }
>
> func (e *Element1) String() string {
> return fmt.Sprintf("Element1:[% x % x]", e.GetInt64Slice(), 
> e.GetByteSlice())
> }
>
> type Element2 struct {
> underlyBuf []byte  // <- is this field needed?
> int64s []int64
> bs []byte
> }
>
> func newElement2(int64Sz, bsSz int) *Element2 {
> assert(int64Sz > 0 && bsSz > 0)
> len0 := int64Sz * 8
> len1 := bsSz
> buf := make([]byte, len0+len1)
> for i := range buf {
> buf[i] = byte(i)
> }
> e := {
> underlyBuf: buf,   // <-
> int64s: unsafe.Slice((*int64)(unsafe.Pointer([0])), 
> int64Sz),
> bs: unsafe.Slice((*byte)([len0]), bsSz),
> }
> return e
> }
>
> func (e *Element2) GetInt64Slice() []int64 {
> runtime.KeepAlive(e.underlyBuf)
> return e.int64s
> }
>
> func (e *Element2) GetByteSlice() []byte {
> runtime.KeepAlive(e.underlyBuf)
> return e.bs
> }
>
> func (e *Element2) String() string {
> runtime.KeepAlive(e.underlyBuf)
> return fmt.Sprintf("Element2:[% x % x]", e.GetInt64Slice(), 
> e.GetByteSlice())
> }
>
> func main() {
> var e Elementer
> fmt.Println("print with host endian:")
> e = newElement1(2, 4)
> fmt.Println("hi", e)
> e = newElement2(2, 4)
> fmt.Println("hi", e)
> }
> ```
>
> And which yields:
>
> ```
> hi Element1:[[ 706050403020100  f0e0d0c0b0a0908] 10 11 12 13]
> hi Element2:[[ 706050403020100  f0e0d0c0b0a0908] 10 11 12 13]
> ```
>
> I'm not sure whether the `underlyBuf` filed in `Element2` is needed or 
> not. When I'm reading the doc from `
> https://pkg.go.dev/reflect#SliceHeader` 
> <https://pkg.go.dev/reflect#SliceHeader> there is:
>
> > Moreover, the Data field is not sufficient to guarantee the data it 
> references will not be garbage collected, so programs must keep a separate, 
> correctly typed pointer to the underlying data.
>
> But in `https://pkg.go.dev/unsafe#Slice` <https://pkg.go.dev/unsafe#Slice> 
> there are no such comments. So the question:
>
> Which implementation of `Elementer` is correct? `Element2` or both of them?
>
> Thanks a lot for your help.
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/3af951b7-2e5c-40d2-8b61-ddc59c97eef3n%40googlegroups.com.


[go-nuts] A Question about `unsafe.Slice`

2022-02-05 Thread rmfr
Please take a look at the following code:

```go
package main

import (
"fmt"
"runtime"
"unsafe"
)

func assert(b bool) {
if b {
} else {
panic("unexpected")
}
}

type Elementer interface {
GetInt64Slice() []int64
GetByteSlice() []byte
String() string
}

type Element1 struct {
int64s []int64
bs []byte
}

func newElement1(int64Sz, bsSz int) *Element1 {
assert(int64Sz > 0 && bsSz > 0)
len0 := int64Sz * 8
len1 := bsSz
buf := make([]byte, len0+len1)
for i := range buf {
buf[i] = byte(i)
}
e := {
int64s: unsafe.Slice((*int64)(unsafe.Pointer([0])), int64Sz),
bs: unsafe.Slice((*byte)([len0]), bsSz),
}
return e
}

func (e *Element1) GetInt64Slice() []int64 {
return e.int64s
}

func (e *Element1) GetByteSlice() []byte {
return e.bs
}

func (e *Element1) String() string {
return fmt.Sprintf("Element1:[% x % x]", e.GetInt64Slice(), 
e.GetByteSlice())
}

type Element2 struct {
underlyBuf []byte  // <- is this field needed?
int64s []int64
bs []byte
}

func newElement2(int64Sz, bsSz int) *Element2 {
assert(int64Sz > 0 && bsSz > 0)
len0 := int64Sz * 8
len1 := bsSz
buf := make([]byte, len0+len1)
for i := range buf {
buf[i] = byte(i)
}
e := {
underlyBuf: buf,   // <-
int64s: unsafe.Slice((*int64)(unsafe.Pointer([0])), 
int64Sz),
bs: unsafe.Slice((*byte)([len0]), bsSz),
}
return e
}

func (e *Element2) GetInt64Slice() []int64 {
runtime.KeepAlive(e.underlyBuf)
return e.int64s
}

func (e *Element2) GetByteSlice() []byte {
runtime.KeepAlive(e.underlyBuf)
return e.bs
}

func (e *Element2) String() string {
runtime.KeepAlive(e.underlyBuf)
return fmt.Sprintf("Element2:[% x % x]", e.GetInt64Slice(), 
e.GetByteSlice())
}

func main() {
var e Elementer
fmt.Println("print with host endian:")
e = newElement1(2, 4)
fmt.Println("hi", e)
e = newElement2(2, 4)
fmt.Println("hi", e)
}
```

And which yields:

```
hi Element1:[[ 706050403020100  f0e0d0c0b0a0908] 10 11 12 13]
hi Element2:[[ 706050403020100  f0e0d0c0b0a0908] 10 11 12 13]
```

I'm not sure whether the `underlyBuf` filed in `Element2` is needed or not. 
When I'm reading the doc from `https://pkg.go.dev/reflect#SliceHeader` 
there is:

> Moreover, the Data field is not sufficient to guarantee the data it 
references will not be garbage collected, so programs must keep a separate, 
correctly typed pointer to the underlying data.

But in `https://pkg.go.dev/unsafe#Slice` there are no such comments. So the 
question:

Which implementation of `Elementer` is correct? `Element2` or both of them?

Thanks a lot for your help.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5da1eda9-536a-4553-8405-0551792ae449n%40googlegroups.com.


Re: [go-nuts] The right way for golang binary to reduce iTLB cache miss

2021-09-18 Thread rmfr
I have tried to disable the inline during compiling, but it results in no 
big difference.

On Saturday, September 18, 2021 at 9:26:45 PM UTC+8 ren...@ix.netcom.com 
wrote:

> I will add that over aggressive inlining can cause this - it explodes the 
> binary size.
>
> On Sep 18, 2021, at 7:37 AM, Jesper Louis Andersen <
> jesper.lou...@gmail.com> wrote:
>
> On Fri, Sep 17, 2021 at 11:09 AM rmfr  wrote:
>
>> One of our Golang applications has a very huge binary size and the size 
>> of the .text segment itself in the elf is approximately *34MB*. The iTLB 
>> load miss reaches about *87%* of all iTLB cache hits.
>>
>> Is there any advice for big Golang applications to reduce the iTLB cache 
>> miss? Two solutions come to me, PGO 
>> <https://en.wikipedia.org/wiki/Profile-guided_optimization> and using 
>> hugepages to load the .text segment. But they are both seem very difficult 
>> to implement in Golang.
>>
>>
>>
> Shot in the dark: is the application running next to some other 
> application on the hardware which wipes the TLB?
>
> -- 
> 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...@googlegroups.com.
>
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAGrdgiWDY%2Bjh2%3DPzAatJU5Ckit0_maex%3DgGC3E4M-t8VB94Qig%40mail.gmail.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/CAGrdgiWDY%2Bjh2%3DPzAatJU5Ckit0_maex%3DgGC3E4M-t8VB94Qig%40mail.gmail.com?utm_medium=email_source=footer>
> .
>
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/7de12443-2916-4190-a08d-0825605f6ca5n%40googlegroups.com.


Re: [go-nuts] The right way for golang binary to reduce iTLB cache miss

2021-09-18 Thread rmfr
The problem is this application is a quite big Golang project. It has about 
500, 000 lines of Golang codes and didn't even count these required 3-rd 
party libraries.

On Sunday, September 19, 2021 at 8:47:44 AM UTC+8 rmfr wrote:

> One of our Golang applications has a very huge binary size and the size of 
> the .text segment itself in the elf is approximately *34MB*. The iTLB 
> load miss reaches about *87%* of all iTLB cache hits.
>
> >> Is there any advice for big Golang applications to reduce the iTLB 
> cache miss? Two solutions come to me, PGO 
> <https://en.wikipedia.org/wiki/Profile-guided_optimization> and using 
> hugepages to load the .text segment. But they are both seem very difficult 
> to implement in Golang.
>
> > Shot in the dark: is the application running next to some other 
> application on the hardware which wipes the TLB?
>
> Nope, it occupies a standalone x86 physical server.
>
>>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/12a18e2b-e860-4ee5-8c64-8b5801dce3f9n%40googlegroups.com.


Re: [go-nuts] The right way for golang binary to reduce iTLB cache miss

2021-09-18 Thread rmfr
One of our Golang applications has a very huge binary size and the size of 
the .text segment itself in the elf is approximately *34MB*. The iTLB load 
miss reaches about *87%* of all iTLB cache hits.

>> Is there any advice for big Golang applications to reduce the iTLB cache 
miss? Two solutions come to me, PGO 
 and using 
hugepages to load the .text segment. But they are both seem very difficult 
to implement in Golang.

> Shot in the dark: is the application running next to some other 
application on the hardware which wipes the TLB?

Nope, it occupies a standalone x86 physical server.

>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/60aa2e83-6639-4c91-be34-37351ebf70b7n%40googlegroups.com.


Re: [go-nuts] Re: The right way for golang binary to reduce iTLB cache miss

2021-09-17 Thread rmfr
Thanks a lot :-D

> This is the icache or code - not the data the code is accessing. 

Yes, it is the cache miss of iTLB, i.e. *Instruction* Translation Lookaside 
Buffer.

I have tried the https://github.com/facebookincubator/BOLT, but the linker 
Golang used seems does not allow `--emit-relocs` option. I also 
tried libhugetlbfs, but it seems could not be applied to Golang.
On Friday, September 17, 2021 at 9:34:52 PM UTC+8 ren...@ix.netcom.com 
wrote:

> This is the icache or code - not the data the code is accessing. 
>
> On Sep 17, 2021, at 8:12 AM, peterGo  wrote:
>
> 
> rmfr,
>
> What is your data, what is its structure, and what are the access paths 
> and frequencies?
>
> Your data is unlikely to be a randomly accessed blob of bits. Is there a 
> set of Pareto access paths that you can use to order your data by access 
> frequency? You want the most frequently accessed data to be adjacent. 
>
> Peter
>
>
> On Friday, September 17, 2021 at 5:09:32 AM UTC-4 rmfr wrote:
>
>> One of our Golang applications has a very huge binary size and the size 
>> of the .text segment itself in the elf is approximately *34MB*. The iTLB 
>> load miss reaches about *87%* of all iTLB cache hits.
>>
>> Is there any advice for big Golang applications to reduce the iTLB cache 
>> miss? Two solutions come to me, PGO 
>> <https://en.wikipedia.org/wiki/Profile-guided_optimization> and using 
>> hugepages to load the .text segment. But they are both seem very difficult 
>> to implement in Golang.
>>
> -- 
> 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...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/1778bb58-e2e1-4bba-a869-1effb1e3952an%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/1778bb58-e2e1-4bba-a869-1effb1e3952an%40googlegroups.com?utm_medium=email_source=footer>
> .
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5d680b74-dec8-4475-813f-3dca33c71d13n%40googlegroups.com.


[go-nuts] The right way for golang binary to reduce iTLB cache miss

2021-09-17 Thread rmfr
One of our Golang applications has a very huge binary size and the size of 
the .text segment itself in the elf is approximately *34MB*. The iTLB load 
miss reaches about *87%* of all iTLB cache hits.

Is there any advice for big Golang applications to reduce the iTLB cache 
miss? Two solutions come to me, PGO 
 and using 
hugepages to load the .text segment. But they are both seem very difficult 
to implement in Golang.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/7cd2ee08-aeda-4b3e-8df3-8d31460340aan%40googlegroups.com.


Re: [go-nuts] What happens if Golang calls a shared .so library via cgo but this library is built from Golang?

2021-08-20 Thread rmfr
> I mean that while it may accidentally happen to work today, it may
> break in future releases. If it does break, we will not fix it to
> work again. You should not assume that this will continue to behave
> in the future as it behaves today.

I get it. Thanks a lot, Ian :-D

On Saturday, August 21, 2021 at 3:00:35 AM UTC+8 Ian Lance Taylor wrote:

> On Thu, Aug 19, 2021 at 7:30 PM rmfr  wrote:
> >
> > Thanks a lot, Ian :-)
> >
> > > Assuming you are running on an ELF system and control symbol
> > visibility, this can work.
> > > To be clear, this is not supported by the Go project.
> >
> > Do you mean that this usage is not recommended in a production 
> environment?
> > And this usage maybe no longer supported by Golang runtime in future 
> updates?
>
> I mean that while it may accidentally happen to work today, it may
> break in future releases. If it does break, we will not fix it to
> work again. You should not assume that this will continue to behave
> in the future as it behaves today.
>
> Ian
>
>
>
> > On Friday, August 20, 2021 at 3:19:22 AM UTC+8 Ian Lance Taylor wrote:
> >>
> >> On Thu, Aug 19, 2021 at 6:34 AM rmfr  wrote:
> >> >
> >> > As the title describes, does this is allowed by the Golang's design? 
> If it is allowed, I think there would be at least two Golang runtime 
> running in the same process space, am I correct?
> >>
> >> Assuming you are running on an ELF system and control symbol
> >> visibility, this can work. As you say, you would have two different
> >> Go runtimes in the same process, competing for access to the CPU and
> >> virtual memory. To be clear, this is not supported by the Go project.
> >>
> >> 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...@googlegroups.com.
> > To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/d787ab62-b1b7-4dd1-a2c9-cf8d3d7a4cb4n%40googlegroups.com
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f8a730e7-5573-4308-8102-1660e31313e6n%40googlegroups.com.


Re: [go-nuts] What happens if Golang calls a shared .so library via cgo but this library is built from Golang?

2021-08-20 Thread rmfr
> Perhaps what you're trying to achieve can be done using Go Plugins 
 instead, although beware of significant 
restrictions:

Thanks Brian, I have looked at it, but I am afraid its usage conditions are 
too strict.

On Friday, August 20, 2021 at 4:10:24 PM UTC+8 Brian Candler wrote:

> Perhaps what you're trying to achieve can be done using Go Plugins 
>  instead, although beware of significant 
> restrictions:
>
>
> https://medium.com/learning-the-go-programming-language/writing-modular-go-programs-with-plugins-ec46381ee1a9
>
> https://www.reddit.com/r/golang/comments/b6h8qq/is_anyone_actually_using_go_plugins/ejkxd2k/?utm_source=reddit_medium=web2x=3
>
> Summary: "it's a bad idea except for in-tree plugins"
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/229b694b-9e60-4867-b81c-1014d0930aa6n%40googlegroups.com.


Re: [go-nuts] What happens if Golang calls a shared .so library via cgo but this library is built from Golang?

2021-08-19 Thread rmfr
Thanks a lot, Ian :-)

> Assuming you are running on an ELF system and control symbol
visibility, this can work.
> To be clear, this is not supported by the Go project.

Do you mean that this usage is not recommended in a production environment? 
And this usage maybe no longer supported by Golang runtime in future 
updates?
On Friday, August 20, 2021 at 3:19:22 AM UTC+8 Ian Lance Taylor wrote:

> On Thu, Aug 19, 2021 at 6:34 AM rmfr  wrote:
> >
> > As the title describes, does this is allowed by the Golang's design? If 
> it is allowed, I think there would be at least two Golang runtime running 
> in the same process space, am I correct?
>
> Assuming you are running on an ELF system and control symbol
> visibility, this can work. As you say, you would have two different
> Go runtimes in the same process, competing for access to the CPU and
> virtual memory. To be clear, this is not supported by the Go project.
>
> 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/d787ab62-b1b7-4dd1-a2c9-cf8d3d7a4cb4n%40googlegroups.com.


[go-nuts] Re: What happens if Golang calls a shared .so library via cgo but this library is built from Golang?

2021-08-19 Thread rmfr
I just test go1.17 call go1.16.6's application shared library, it works 
(one binary dumps two different golang's runtime version):

```
Go version: go1.16.6
Go version: go1.17
```

On Thursday, August 19, 2021 at 9:36:43 PM UTC+8 rmfr wrote:

> Please also consider what happens if this two Golang has two different 
> version :-D
>
> On Thursday, August 19, 2021 at 9:33:39 PM UTC+8 rmfr wrote:
>
>> Hi,
>>
>> As the title describes, does this is allowed by the Golang's design? If 
>> it is allowed, I think there would be at least two Golang runtime running 
>> in the same process space, am I correct?
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5928ef2a-8841-4aeb-a12a-bac7bfbe8856n%40googlegroups.com.


[go-nuts] Re: What happens if Golang calls a shared .so library via cgo but this library is built from Golang?

2021-08-19 Thread rmfr
I just test go1.17 call go1.16.6's application shared library, it works 
(one binary dumps two different golang's runtime version):

```
ha!
Go version: go1.16.6
Go version: go1.17
```



On Thursday, August 19, 2021 at 9:36:43 PM UTC+8 rmfr wrote:

> Please also consider what happens if this two Golang has two different 
> version :-D
>
> On Thursday, August 19, 2021 at 9:33:39 PM UTC+8 rmfr wrote:
>
>> Hi,
>>
>> As the title describes, does this is allowed by the Golang's design? If 
>> it is allowed, I think there would be at least two Golang runtime running 
>> in the same process space, am I correct?
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/7a76abfc-751d-4952-85c3-5ac869ad7a59n%40googlegroups.com.


[go-nuts] Re: What happens if Golang calls a shared .so library via cgo but this library is built from Golang?

2021-08-19 Thread rmfr
Please also consider what happens if this two Golang has two different 
version :-D

On Thursday, August 19, 2021 at 9:33:39 PM UTC+8 rmfr wrote:

> Hi,
>
> As the title describes, does this is allowed by the Golang's design? If it 
> is allowed, I think there would be at least two Golang runtime running in 
> the same process space, am I correct?

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/0bb00570-0fbf-4669-be42-464af31e7bccn%40googlegroups.com.


[go-nuts] What happens if Golang calls a shared .so library via cgo but this library is built from Golang?

2021-08-19 Thread rmfr
Hi,

As the title describes, does this is allowed by the Golang's design? If it 
is allowed, I think there would be at least two Golang runtime running in 
the same process space, am I correct?

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/918c329a-e2ca-43af-9e8f-8ee669ca954an%40googlegroups.com.


[go-nuts] A question about metric `/sched/latencies:seconds` in go1.17's package runtime/metrics

2021-08-18 Thread rmfr
Hi,

I am reading the description of metric `/sched/latencies:seconds` in 
runtime/metrics:

```
/sched/latencies:seconds 

Distribution of the time goroutines have spent in the scheduler in a 
runnable state before actually running.
```

I wonder such records are from all the goroutines' `runnable` state time 
measurement, or just sampling?

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/b0bbac49-75d3-4d2e-9efb-2d7c238f0f13n%40googlegroups.com.


[go-nuts] How to correctly set a larger maxTinySize ?

2021-08-05 Thread rmfr
I want to set a larger maxTinySize and see what the runtime will behave. 
Then I made these changes to the sources of go1.16.6:

// go/src/runtime/malloc.go 
const (
  debugMalloc = false

  maxTinySize   = _TinySize
  tinySizeClass = _TinySizeClass

  // Tiny allocator parameters, see "Tiny allocator" comment in malloc.go.
  _TinySize  = *32*
  _TinySizeClass = int8(*4*)
  /* ... */
}

And run the make scripts on a amd64 linux box, but it yields:

$./make.bash
 
Building Go cmd/dist using /usr/local/go. (go1.16 linux/amd64)
Building Go toolchain1 using /usr/local/go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
panic: sync: WaitGroup is reused before previous Wait has returned

goroutine 1 [running]:
sync.(*WaitGroup).Wait(0xc0003a40f4)
/mnt/down/ework/src/go2/go/src/sync/waitgroup.go:132 +0xae
cmd/go/internal/work.(*Builder).Do(0xc000354d20, 0x910750, 0xc8c000, 
0xc00030e3c0)
/mnt/down/ework/src/go2/go/src/cmd/go/internal/work/exec.go:207 
+0x559
cmd/go/internal/work.InstallPackages(0x910750, 0xc8c000, 0xca8050, 
0x4, 0x4, 0xc00026ab00, 0x4, 0x4)
/mnt/down/ework/src/go2/go/src/cmd/go/internal/work/build.go:724 
+0xc3e
cmd/go/internal/work.runInstall(0x910750, 0xc8c000, 0xae6480, 
0xca8050, 0x4, 0x4)
/mnt/down/ework/src/go2/go/src/cmd/go/internal/work/build.go:632 
+0x38c
main.main()
/mnt/down/ework/src/go2/go/src/cmd/go/main.go:195 +0x70c
go tool dist: FAILED: 
/mnt/down/ework/src/go2/go/pkg/tool/linux_amd64/go_bootstrap install 
-gcflags=all=-ldflags=all= -i cmd/asm cmd/cgo cmd/compile cmd/link: exit 
status 2

Am I missing something? I would be highly appreciated it if anyone could 
give me a direction. Thanks a lot :-D

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/b0808ad5-0a44-4a43-a6ec-010a91c76e69n%40googlegroups.com.


Re: [go-nuts] Does the time cost of the mark phase in gc is mainly depending on the amount of the living objects and has very little to do with the amount of unused objects?

2021-07-28 Thread rmfr
Thank you very much, Ian. You gave me a deeper understanding of Golang's 
internal :-D

On Wednesday, July 28, 2021 at 6:23:02 AM UTC+8 Ian Lance Taylor wrote:

> On Tue, Jul 27, 2021 at 4:56 AM rmfr  wrote:
> >
> > Hi, I'm reading the GC implementation of Golang, and some questions have 
> come to me. As the title described:
> >
> > Proposition 1:
> > The time cost of the mark phase in GC is mainly depending on the amount 
> of the living objects.
> >
> > Proposition 2:
> > The time cost of the mark phase in GC has very little to do with the 
> amount of unused objects.
> >
> > Do both propositions above is true? Thanks a lot.
>
> Yes, both statements are generally true.
>
> That said, since Go's garbage collector runs concurrently with the
> rest of the program, it's a little hard to know what "the time cost of
> the mark phase" is. But it is true that in general during marking the
> GC only looks at live objects.
>
> 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/43f75cf1-2762-4aff-a29d-a8411f6cba91n%40googlegroups.com.


[go-nuts] Does the time cost of the mark phase in gc is mainly depending on the amount of the living objects and has very little to do with the amount of unused objects?

2021-07-27 Thread rmfr
Hi, I'm reading the GC implementation of Golang, and some questions have 
come to me. As the title described:

Proposition 1:
The time cost of the mark phase in GC is mainly depending on the amount 
of the living objects.

Proposition 2:
The time cost of the mark phase in GC has very little to do with the 
amount of unused objects.

Do both propositions above is true? Thanks a lot.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/4c16ed7f-f911-47ec-9886-11cf72396d51n%40googlegroups.com.


[go-nuts] Re: How to Optimize A Golang Application Which Has More Than 100 Million Objects at Peak?

2021-07-19 Thread rmfr
Thanks a lot! You are so kind and nice :-D

I tried golang's heap profile and found it is very helpful. By the way, 
what do you think about this article:

https://dgraph.io/blog/post/manual-memory-management-golang-jemalloc/

On Sunday, July 18, 2021 at 11:27:38 PM UTC+8 jake...@gmail.com wrote:

> Two other replies have mentioned Sync.Pool. I agree that Sync.Pool is a 
> valuable tool. 
>
> However, for the benefit of any beginning gophers who may read this 
> thread, I wanted to point out that, in a situation like yours, I would want 
> to try to reduce heap allocation in other ways first. Not that Sync.pool is 
> a last resort exactly, but it does have non-trivial overhead, and is not a 
> substitute for thinking about other ways to clean up heap allocations. For 
> example, pulling allocations out of loops, or manual object re-use where it 
> fits naturally into the code.
>
> On Friday, July 16, 2021 at 8:27:03 AM UTC-4 rmfr wrote:
>
>> I run it at an 8 cores 16GB machine and it occupies all cpu cores it 
>> could.
>>
>> 1. It is ~95% cpu intensive and with ~5% network communications.
>>
>> 2. The codebase is huge and has more than 300 thousands of lines of code 
>> (even didn't count the third party library yet).
>>
>> 3. The tool pprof tells nearly 50% percent of the time is spending on the 
>> runtime, something related to gc, mallocgc, memclrNoHeapPointers, and so on.
>>
>> 4. It has ~100 million dynamic objects.
>>
>> Do you guys have some good advice to optimize the performance?
>>
>> One idea that occurs to me is to do something like sync.Pool to buffer 
>> some most frequently allocated and freed objects. But the problem is I 
>> didn't manage to find a golang tool to find such objects. The runtime 
>> provides api to get the amount of objects but it didn't provide api to get 
>> the detailed statistics of all objects. Please correct me if I'm wrong. 
>> Thanks a lot :-)
>>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/9708e407-60ab-4e0d-97df-e3f6b5997dd4n%40googlegroups.com.


[go-nuts] How to Optimize A Golang Application Which Has More Than 100 Million Objects at Peak?

2021-07-16 Thread rmfr
I run it at an 8 cores 16GB machine and it occupies all cpu cores it could.

1. It is ~95% cpu intensive and with ~5% network communications.

2. The codebase is huge and has more than 300 thousands of lines of code 
(even didn't count the third party library yet).

3. The tool pprof tells nearly 50% percent of the time is spending on the 
runtime, something related to gc, mallocgc, memclrNoHeapPointers, and so on.

4. It has ~100 million dynamic objects.

Do you guys have some good advice to optimize the performance?

One idea that occurs to me is to do something like sync.Pool to buffer some 
most frequently allocated and freed objects. But the problem is I didn't 
manage to find a golang tool to find such objects. The runtime provides api 
to get the amount of objects but it didn't provide api to get the detailed 
statistics of all objects. Please correct me if I'm wrong. Thanks a lot :-)

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/950ce206-55a7-4eef-bab5-d4ffe0384b98n%40googlegroups.com.


[go-nuts] Re: Does current GC move object now?

2021-03-13 Thread rmfr
Maybe the reason for such a strict rule on using cgo is just to take 
precautions if our GC moves object in the future? And at that time, the 
syscall implementation must be rewritten to add some codes to pinning the 
objects used by each syscall from being moved. Am I correct?

On Sunday, March 14, 2021 at 2:11:18 PM UTC+8 rmfr wrote:

> I am watching the implementation of syscall `writev` from [here](
> https://github.com/golang/sys/blob/bd2e13477e9c63125302cd9da2d61879c6aa1721/unix/zsyscall_linux.go#L1641),
>  
> and comparing it with the [proposal](
> https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md) 
> of cgo. I found the rule applies on cgo and syscall is inconsistent. 
>
> If the object could be moved during GC, then the code to implement 
> `writev` is incorrect. Because GC could happen during the syscall and the 
> byte slices kernel is using has been moved! :-(
>
> If the object may not be moved during GC, then the code to implement 
> syscall `writev` is correct. But from the perspective of go runtime, cgo is 
> just a kind of special "syscall", then the rule applies to cgo now is far 
> too strict -- you simply couldn't call a C API like `writev` which takes 
> array of byte slices as input arg (because the rule applies on cgo now only 
> allow one input arg contains at most one go pointer).
>
> Maybe I have missed something, please correct me. Thanks a lot for your 
> patient and kindness :-)
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/57c3f2e9-e28c-43e3-b765-b33434b6d1f5n%40googlegroups.com.


[go-nuts] Does current GC move object now?

2021-03-13 Thread rmfr
I am watching the implementation of syscall `writev` from 
[here](https://github.com/golang/sys/blob/bd2e13477e9c63125302cd9da2d61879c6aa1721/unix/zsyscall_linux.go#L1641),
 
and comparing it with the 
[proposal](https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md)
 
of cgo. I found the rule applies on cgo and syscall is inconsistent. 

If the object could be moved during GC, then the code to implement `writev` 
is incorrect. Because GC could happen during the syscall and the byte 
slices kernel is using has been moved! :-(

If the object may not be moved during GC, then the code to implement 
syscall `writev` is correct. But from the perspective of go runtime, cgo is 
just a kind of special "syscall", then the rule applies to cgo now is far 
too strict -- you simply couldn't call a C API like `writev` which takes 
array of byte slices as input arg (because the rule applies on cgo now only 
allow one input arg contains at most one go pointer).

Maybe I have missed something, please correct me. Thanks a lot for your 
patient and kindness :-)

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a6e88a30-a8e2-4745-93ee-cf79fa636d8dn%40googlegroups.com.


[go-nuts] Re: How to call a C `writev` styled library api via cgo without allocation and copying of the whole byte slice vector?

2021-03-13 Thread rmfr
I have read this proposal 
carefully 
https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md#proposal
   
   1. Go code may pass a Go pointer to C provided that the Go memory to 
   which it points does not contain any Go pointers.


   - The C code must not store any Go pointers in Go memory, even 
   temporarily.
   - When passing a pointer to a field in a struct, the Go memory in 
   question is the memory occupied by the field, not the entire struct.
   - When passing a pointer to an element in an array or slice, the Go 
   memory in question is the entire array or the entire backing array of the 
   slice.
   - *Passing a Go pointer to C code means that that Go pointer is visible 
   to C code; passing one Go pointer does not cause any other Go pointers to 
   become visible.*
   - *The maximum number of Go pointers that can become visible to C code 
   in a single function call is the number of arguments to the function.*

 So does it is correct that you cannot call some C api like `writev` safely 
without concatenating all the byte slices together into one big byte slice?

On Saturday, March 13, 2021 at 10:24:52 PM UTC+8 rmfr wrote:

> Say here is a C api like `ssize_t writev(const struct iovec *iov, int 
> iovcnt)` which the definition of iovec is like below:
>
> ```
> struct iovec {
>  uint8_t   *Base;  /* Base address. */
>  uint64_t Len;/* Length. */
>  };
> ```
>
> For C api which like `ssize_t write(const void *buf, size_t nbyte)`, the 
> solution would be quite straight forward:
>
> ```
> bs := make([]byte, 1024*1024*512)
> // without extra memory allocation and copying of the whole input byte 
> slice :-D
> rc := C.write(unsafe.Pointer([0]), C.int(len(bs)))
> ```
>
> But how to call C `writev` style API without extra memory allocation or 
> copying of the whole byte slice vector?
>
> ```
> bsv := make([][]byte, 1024)
> for i := range bsv{
> bsv[i] = make([]byte, 5*1024*(rand.Intn(i)+1))
> }
> // assuming that allocation of a iovec array is acceptable
> // but allocation and copying of all bsv[x] byte slice member is 
> unacceptable
> //
> iovec := make([]syscall.Iovec, len(bsv))
> for i := range bsv {
> bs := bsv[i]
> if len(bs) > 0 {
> iovec[i].Base = unsafe.Pointer([0])
> iovec[i].Len = uint64(len(bs))
> }
> }
> //
> // rc := C.writev( /* how? :-( */)
> rc := C.writev(unsafe.Pointer([0]), C.int(len(iovec))) // Does this 
> code is right and safe?
> ```
>
> Does the code above is right?
>
> I have read cgo's docs carefully, and here is a constraint from 
> https://golang.org/cmd/cgo/#hdr-Passing_pointers:
>
> > Go code may pass a Go pointer to C provided the Go memory to which it 
> points does not contain any Go pointers.
>
> If the Go memory pointed by `unsafe.Pointer([0])` contains pointer 
> which points to these byte slice members of bsv, so it would be a 
> *violation* of the cgo constraint above. And that means you could not 
> call C `writev` style API without allocation and copying of the whole 
> vector.
>
> Please correct me if I get something wrong. Thanks a lot :-D
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ed9086ad-db73-489c-8bd5-dc2c17639ffan%40googlegroups.com.


[go-nuts] How to call a C `writev` styled library api via cgo without allocation and copying of the whole byte slice vector?

2021-03-13 Thread rmfr
Say here is a C api like `ssize_t writev(const struct iovec *iov, int 
iovcnt)` which the definition of iovec is like below:

```
struct iovec {
 uint8_t   *Base;  /* Base address. */
 uint64_t Len;/* Length. */
 };
```

For C api which like `ssize_t write(const void *buf, size_t nbyte)`, the 
solution would be quite straight forward:

```
bs := make([]byte, 1024*1024*512)
// without extra memory allocation and copying of the whole input byte 
slice :-D
rc := C.write(unsafe.Pointer([0]), C.int(len(bs)))
```

But how to call C `writev` style API without extra memory allocation or 
copying of the whole byte slice vector?

```
bsv := make([][]byte, 1024)
for i := range bsv{
bsv[i] = make([]byte, 5*1024*(rand.Intn(i)+1))
}
// assuming that allocation of a iovec array is acceptable
// but allocation and copying of all bsv[x] byte slice member is 
unacceptable
//
iovec := make([]syscall.Iovec, len(bsv))
for i := range bsv {
bs := bsv[i]
if len(bs) > 0 {
iovec[i].Base = unsafe.Pointer([0])
iovec[i].Len = uint64(len(bs))
}
}
//
// rc := C.writev( /* how? :-( */)
rc := C.writev(unsafe.Pointer([0]), C.int(len(iovec))) // Does this 
code is right and safe?
```

Does the code above is right?

I have read cgo's docs carefully, and here is a constraint from 
https://golang.org/cmd/cgo/#hdr-Passing_pointers:

> Go code may pass a Go pointer to C provided the Go memory to which it 
points does not contain any Go pointers.

If the Go memory pointed by `unsafe.Pointer([0])` contains pointer 
which points to these byte slice members of bsv, so it would be a 
*violation* of the cgo constraint above. And that means you could not call 
C `writev` style API without allocation and copying of the whole vector.

Please correct me if I get something wrong. Thanks a lot :-D

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/1638feb7-3f3d-4061-ad70-a031839b7542n%40googlegroups.com.


[go-nuts] Does go programmers should handle syscall.EINTR all by themselves after go1.9 when writing disk files?

2018-02-02 Thread rmfr
Does go programmers should handle syscall.EINTR all by themselves after 
go1.9 when writing disk files?

I just noticed this commit 
https://github.com/golang/go/commit/c05b06a12d005f50e4776095a60d6bd9c2c91fac#diff-b7452e0f27c15f140b5e86f88e2d43deL192

If the answer is 'yes', I wonder why deleted this loop-write-if-eintr 
logic? Does it not bring unnecessary inconvenience to the go programmer?

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