[go-nuts] Re: Strange benchmark results

2021-05-15 Thread peterGo
For your sliceinsert microbenchmarks, you don't provide the Go version, you 
don't provide memory allocation statistics, and you only provide results 
for a single data point.

My results for several values of N:

https://play.golang.org/p/WuKmIy_jY20

There are significant differences in CPU performance for different values 
of N, ranging from 1:1 to 2:1 for append versus precise implementations.

I am unable reproduce your result.

Peter

On Thursday, May 13, 2021 at 4:52:32 AM UTC-4 tapi...@gmail.com wrote:

>
> package main
>
> import "testing"
>
> const N = 1615119
> // It is strange that if N is large enough,
> // the one line implementations are fast as the others.
> // And if N is odd number, the InsertOneline_Disassemble
> // implementation is about 10% faster than the others.
>
> func init() {
> println(" N =", N)
> }
>
> func InsertOneline(s []int, k int, vs ...int) []int {
> return append(s[:k], append(vs, s[k:]...)...)
> }
>
> func InsertOneline_Disassemble(s []int, k int, vs ...int) []int {
> z := append(vs, s[k:]...)
> return append(s[:k], z...)
> }
>
> func InsertVerbose(s []int, k int, vs ...int) []int {
> if n := len(s) + len(vs); n <= cap(s) {
> s2 := s[:n]
> copy(s2[k+len(vs):], s[k:])
> copy(s2[k:], vs)
> return s2
> }
> s2 := make([]int, len(s) + len(vs))
> copy(s2, s[:k])
> copy(s2[k:], vs)
> copy(s2[k+len(vs):], s[k:])
> return s2
> }
>
>
> func InsertVerbose_b(s []int, k int, vs ...int) []int {
> if n := len(s) + len(vs); n <= cap(s) {
> s2 := s[:n]
> copy(s2[k+len(vs):], s[k:])
> copy(s2[k:], vs)
> return s2
> }
> s2 := make([]int, 0, len(s) + len(vs))
> s2 = append(s2, s[:k]...)
> s2 = append(s2, vs...)
> s2 = append(s2, s[k:]...)
> return s2
> }
>
> func InsertVerbose_c(s []int, k int, vs ...int) []int {
> if n := len(s) + len(vs); n <= cap(s) {
> s2 := s[:n]
> copy(s2[k+len(vs):], s[k:])
> copy(s2[k:], vs)
> return s2
> }
> s2 := append([]int(nil), make([]int, len(s) + len(vs))...)[:0]
> s2 = append(s2, s[:k]...)
> s2 = append(s2, vs...)
> s2 = append(s2, s[k:]...)
> return s2
> }
>
> var s1 []int
> func Benchmark_InsertOneline(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/5
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s1 = InsertOneline(x, k, y...)
> }
> }
>
> var s1b []int
> func Benchmark_InsertOneline_Disassemble(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/2
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s1b = InsertOneline_Disassemble(x, k, y...)
> }
> }
>
> var s2 []int
> func Benchmark_InsertVerbose(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/2
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s2 = InsertVerbose(x, k, y...)
> }
> }
>
> var s3 []int
> func Benchmark_InsertVerbose_b(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/2
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s3 = InsertVerbose_b(x, k, y...)
> }
> }
>
> var s4 []int
> func Benchmark_InsertVerbose_c(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/2
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s4 = InsertVerbose_c(x, k, y...)
> }
> }
>
>
> The result:
>
> $ go test -bench=. -benchtime=3s
>  N = 1615119
> goos: linux
> goarch: amd64
> pkg: a.y/bench/sliceinsert
> cpu: Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz
> Benchmark_InsertOneline-4693   4741509 ns/op
> Benchmark_InsertOneline_Disassemble-4871   4194142 ns/op
> Benchmark_InsertVerbose-4764   4627334 ns/op
> Benchmark_InsertVerbose_b-4  769   4958537 ns/op
> Benchmark_InsertVerbose_c-4  661   4855514 ns/op
>

-- 
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/a60e7ea0-008c-47e8-8913-55ec91da43fcn%40googlegroups.com.


[go-nuts] Re: Strange benchmark results

2021-05-15 Thread peter so
For your sliceinsert microbenchmarks, you don't provide the Go version, you 
don't provide memory allocation statistics, and you only provide results 
for a single data point.

My results for several values of N:

https://play.golang.org/p/WuKmIy_jY20

There are significant differences in CPU performance for different values 
of N, ranging from 1:1 to 2:1 for append versus precise implementations.

I am unable reproduce your result.

Peter


On Thursday, May 13, 2021 at 4:52:32 AM UTC-4 tapi...@gmail.com wrote:

>
> package main
>
> import "testing"
>
> const N = 1615119
> // It is strange that if N is large enough,
> // the one line implementations are fast as the others.
> // And if N is odd number, the InsertOneline_Disassemble
> // implementation is about 10% faster than the others.
>
> func init() {
> println(" N =", N)
> }
>
> func InsertOneline(s []int, k int, vs ...int) []int {
> return append(s[:k], append(vs, s[k:]...)...)
> }
>
> func InsertOneline_Disassemble(s []int, k int, vs ...int) []int {
> z := append(vs, s[k:]...)
> return append(s[:k], z...)
> }
>
> func InsertVerbose(s []int, k int, vs ...int) []int {
> if n := len(s) + len(vs); n <= cap(s) {
> s2 := s[:n]
> copy(s2[k+len(vs):], s[k:])
> copy(s2[k:], vs)
> return s2
> }
> s2 := make([]int, len(s) + len(vs))
> copy(s2, s[:k])
> copy(s2[k:], vs)
> copy(s2[k+len(vs):], s[k:])
> return s2
> }
>
>
> func InsertVerbose_b(s []int, k int, vs ...int) []int {
> if n := len(s) + len(vs); n <= cap(s) {
> s2 := s[:n]
> copy(s2[k+len(vs):], s[k:])
> copy(s2[k:], vs)
> return s2
> }
> s2 := make([]int, 0, len(s) + len(vs))
> s2 = append(s2, s[:k]...)
> s2 = append(s2, vs...)
> s2 = append(s2, s[k:]...)
> return s2
> }
>
> func InsertVerbose_c(s []int, k int, vs ...int) []int {
> if n := len(s) + len(vs); n <= cap(s) {
> s2 := s[:n]
> copy(s2[k+len(vs):], s[k:])
> copy(s2[k:], vs)
> return s2
> }
> s2 := append([]int(nil), make([]int, len(s) + len(vs))...)[:0]
> s2 = append(s2, s[:k]...)
> s2 = append(s2, vs...)
> s2 = append(s2, s[k:]...)
> return s2
> }
>
> var s1 []int
> func Benchmark_InsertOneline(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/5
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s1 = InsertOneline(x, k, y...)
> }
> }
>
> var s1b []int
> func Benchmark_InsertOneline_Disassemble(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/2
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s1b = InsertOneline_Disassemble(x, k, y...)
> }
> }
>
> var s2 []int
> func Benchmark_InsertVerbose(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/2
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s2 = InsertVerbose(x, k, y...)
> }
> }
>
> var s3 []int
> func Benchmark_InsertVerbose_b(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/2
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s3 = InsertVerbose_b(x, k, y...)
> }
> }
>
> var s4 []int
> func Benchmark_InsertVerbose_c(b *testing.B) {
> var x = make([]int, N)
> var y = make([]int, N/2)
> var k = N/2
> b.ResetTimer()
> for i := 0; i < b.N; i++ {
> s4 = InsertVerbose_c(x, k, y...)
> }
> }
>
>
> The result:
>
> $ go test -bench=. -benchtime=3s
>  N = 1615119
> goos: linux
> goarch: amd64
> pkg: a.y/bench/sliceinsert
> cpu: Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz
> Benchmark_InsertOneline-4693   4741509 ns/op
> Benchmark_InsertOneline_Disassemble-4871   4194142 ns/op
> Benchmark_InsertVerbose-4764   4627334 ns/op
> Benchmark_InsertVerbose_b-4  769   4958537 ns/op
> Benchmark_InsertVerbose_c-4  661   4855514 ns/op
>

-- 
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/89741678-c394-4ec7-8d7d-adb083e9e4e1n%40googlegroups.com.


[go-nuts] Re: Strange benchmark results

2021-05-15 Thread Brian Candler
With go version go1.16.3 darwin/amd64 (macOS 10.14.6), and after changing 
N/5 to N/2, I can't reproduce either.

$ go test . -bench=. -benchtime=3s
 N = 1615119
goos: darwin
goarch: amd64
pkg: bm
cpu: Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz
Benchmark_InsertOneline-4 8674130473 ns/op
Benchmark_InsertOneline_Disassemble-4 8484161459 ns/op
Benchmark_InsertVerbose-4 6964988955 ns/op
Benchmark_InsertVerbose_b-4   7124882270 ns/op
Benchmark_InsertVerbose_c-4   7024876656 ns/op
PASS
ok  bm 23.058s

InsertOneline_Disassemble-4 is about 0.75% slower than InsertOneline-4, and 
both are significantly faster than the others.

On Friday, 14 May 2021 at 23:49:16 UTC+1 peterGo wrote:

> My results:
>
> https://play.golang.org/p/o2cGAcpNMkX
>
> I can't reproduce your results.
>
> Peter
>
> On Thursday, May 13, 2021 at 4:52:32 AM UTC-4 tapi...@gmail.com wrote:
>
>>
>> package main
>>
>> import "testing"
>>
>> const N = 1615119
>> // It is strange that if N is large enough,
>> // the one line implementations are fast as the others.
>> // And if N is odd number, the InsertOneline_Disassemble
>> // implementation is about 10% faster than the others.
>>
>> func init() {
>> println(" N =", N)
>> }
>>
>> func InsertOneline(s []int, k int, vs ...int) []int {
>> return append(s[:k], append(vs, s[k:]...)...)
>> }
>>
>> func InsertOneline_Disassemble(s []int, k int, vs ...int) []int {
>> z := append(vs, s[k:]...)
>> return append(s[:k], z...)
>> }
>>
>> func InsertVerbose(s []int, k int, vs ...int) []int {
>> if n := len(s) + len(vs); n <= cap(s) {
>> s2 := s[:n]
>> copy(s2[k+len(vs):], s[k:])
>> copy(s2[k:], vs)
>> return s2
>> }
>> s2 := make([]int, len(s) + len(vs))
>> copy(s2, s[:k])
>> copy(s2[k:], vs)
>> copy(s2[k+len(vs):], s[k:])
>> return s2
>> }
>>
>>
>> func InsertVerbose_b(s []int, k int, vs ...int) []int {
>> if n := len(s) + len(vs); n <= cap(s) {
>> s2 := s[:n]
>> copy(s2[k+len(vs):], s[k:])
>> copy(s2[k:], vs)
>> return s2
>> }
>> s2 := make([]int, 0, len(s) + len(vs))
>> s2 = append(s2, s[:k]...)
>> s2 = append(s2, vs...)
>> s2 = append(s2, s[k:]...)
>> return s2
>> }
>>
>> func InsertVerbose_c(s []int, k int, vs ...int) []int {
>> if n := len(s) + len(vs); n <= cap(s) {
>> s2 := s[:n]
>> copy(s2[k+len(vs):], s[k:])
>> copy(s2[k:], vs)
>> return s2
>> }
>> s2 := append([]int(nil), make([]int, len(s) + len(vs))...)[:0]
>> s2 = append(s2, s[:k]...)
>> s2 = append(s2, vs...)
>> s2 = append(s2, s[k:]...)
>> return s2
>> }
>>
>> var s1 []int
>> func Benchmark_InsertOneline(b *testing.B) {
>> var x = make([]int, N)
>> var y = make([]int, N/2)
>> var k = N/5
>> b.ResetTimer()
>> for i := 0; i < b.N; i++ {
>> s1 = InsertOneline(x, k, y...)
>> }
>> }
>>
>> var s1b []int
>> func Benchmark_InsertOneline_Disassemble(b *testing.B) {
>> var x = make([]int, N)
>> var y = make([]int, N/2)
>> var k = N/2
>> b.ResetTimer()
>> for i := 0; i < b.N; i++ {
>> s1b = InsertOneline_Disassemble(x, k, y...)
>> }
>> }
>>
>> var s2 []int
>> func Benchmark_InsertVerbose(b *testing.B) {
>> var x = make([]int, N)
>> var y = make([]int, N/2)
>> var k = N/2
>> b.ResetTimer()
>> for i := 0; i < b.N; i++ {
>> s2 = InsertVerbose(x, k, y...)
>> }
>> }
>>
>> var s3 []int
>> func Benchmark_InsertVerbose_b(b *testing.B) {
>> var x = make([]int, N)
>> var y = make([]int, N/2)
>> var k = N/2
>> b.ResetTimer()
>> for i := 0; i < b.N; i++ {
>> s3 = InsertVerbose_b(x, k, y...)
>> }
>> }
>>
>> var s4 []int
>> func Benchmark_InsertVerbose_c(b *testing.B) {
>> var x = make([]int, N)
>> var y = make([]int, N/2)
>> var k = N/2
>> b.ResetTimer()
>> for i := 0; i < b.N; i++ {
>> s4 = InsertVerbose_c(x, k, y...)
>> }
>> }
>>
>>
>> The result:
>>
>> $ go test -bench=. -benchtime=3s
>>  N = 1615119
>> goos: linux
>> goarch: amd64
>> pkg: a.y/bench/sliceinsert
>> cpu: Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz
>> Benchmark_InsertOneline-4693   4741509 ns/op
>> Benchmark_InsertOneline_Disassemble-4871   4194142 ns/op
>> Benchmark_InsertVerbose-4764   4627334 ns/op
>> Benchmark_InsertVerbose_b-4  769   4958537 ns/op
>> Benchmark_InsertVerbose_c-4  661   4855514 ns/op
>>
>

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

Re: [go-nuts] How can I check error types of gRPC calls?

2021-05-15 Thread 'Axel Wagner' via golang-nuts
Generally, I would argue that the grpc package maintainers should, at some
point, support native wrapping of errors.
In the meantime, they are providing this package:
https://pkg.go.dev/google.golang.org/grpc/status
It predates (by a long time) the errors.Is APIs, which is why I assume they
haven't yet implemented support

On Sat, May 15, 2021 at 1:47 PM cpu...@gmail.com  wrote:

> In my local code, I'm using things like
>
> if errors.Is(err, api.ErrMustRetry) { ... }
>
> How would I achieve the same on errors returned by the gRCP interface?
> I've noticed these are wrapped:
>
> rpc error: code = Unknown desc = must retry rpc error: code = Unknown desc
> = must retry
>
> I assume the errors package won't work here as type information is not
> carried across gRPC: What is the best practice here: unwrap the root error
> from the RPC result (how) and perform string comparison?
>
> Thanks,
> Andreas
>
> --
> 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/c3053cb0-d739-496d-a804-7f533ba7a6cbn%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/CAEkBMfEZ1Ge53nrLAZ7h_tJqrXRTUaBYZg7EV7yi7wzEGwC5Qw%40mail.gmail.com.


Re: [go-nuts] How can I check error types of gRPC calls?

2021-05-15 Thread 'Dan Kortschak' via golang-nuts
On Sat, 2021-05-15 at 04:47 -0700, cpu...@gmail.com wrote:
> In my local code, I'm using things like
>
> if errors.Is(err, api.ErrMustRetry) { ... }
>
> How would I achieve the same on errors returned by the gRCP
> interface? I've noticed these are wrapped:
>
> rpc error: code = Unknown desc = must retry rpc error: code = Unknown
> desc = must retry
>
> I assume the errors package won't work here as type information is
> not carried across gRPC: What is the best practice here: unwrap the
> root error from the RPC result (how) and perform string comparison?
>

There is the status package which provides tools for examining the gRPC
errors, https://pkg.go.dev/google.golang.org/grpc/status.


-- 
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/1ab47e32ab024c2637e199d85b49601b35e54c52.camel%40kortschak.io.


[go-nuts] How can I check error types of gRPC calls?

2021-05-15 Thread cpu...@gmail.com
In my local code, I'm using things like

if errors.Is(err, api.ErrMustRetry) { ... }

How would I achieve the same on errors returned by the gRCP interface? I've 
noticed these are wrapped: 

rpc error: code = Unknown desc = must retry rpc error: code = Unknown desc 
= must retry

I assume the errors package won't work here as type information is not 
carried across gRPC: What is the best practice here: unwrap the root error 
from the RPC result (how) and perform string comparison?

Thanks,
Andreas

-- 
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/c3053cb0-d739-496d-a804-7f533ba7a6cbn%40googlegroups.com.


Re: [go-nuts] Still "missing" priority or ordered select in go?

2021-05-15 Thread Robert Engels
Robert :)

> On May 15, 2021, at 3:48 AM, Øyvind Teig  wrote:
> 
> Thanks, rog. I appreciate this! Even if I cant' stop thinking that a "pri" 
> would have been sligtly more elegant. But you shall be praised for the try! I 
> wont' take the time to fine read the code, though... 
> 
> ..Aside: Being more than busy to digest the fact that XMOS has announced a 
> paradigm shift with keeping the xC compiler, but for new projects wanting us 
> to code "in C" instead, with a library lib_xcore. There are reasons. But 
> ordered select is kept! See my reaction blog note C plus lib_xcore 
> black-boxes xC (disclaimer: no association with XMOS, no ads, no income, no 
> gifts etc with my blogs. Only fun an expensens)
> 
>> torsdag 13. mai 2021 kl. 04:48:31 UTC+2 skrev ren...@ix.netcom.com:
>> Here is a simple priority select implementation using unbuffered channels. 
>> https://play.golang.org/p/Hvl0iMr-cFW
>> 
>> Uncomment the lines as instructed and you will see that channel A is always 
>> picked.
>> 
>> What this demonstrates is that ‘priority’ and ‘event order’ is highly 
>> dependent on latency, event frequency, etc. The ’sleep’ + locks in this 
>> example function as an external clock - as long as all events are ready at 
>> the clock edge you can implement priority - but with async events and 
>> scheduling - priority is impossible.
>> 
>> (In the absence of the sleep - the Go scheduler + OS scheduler determines 
>> whether A or B will run and scheduling delays will allow B events to arrive 
>> before an A event.
>> 
>> You can also trivially change this example to implement the ‘close A, close 
>> B’ scenario using a single Go routine and will see the desired ’never ends’ 
>> state is obtained.
>> 
>> (btw - there are probably some deadlock scenarios - I didn’t spend a lot of 
>> time on this)
>> 
>> 
>> 
>> 
>> 
 On May 12, 2021, at 11:53 AM, Øyvind Teig  wrote:
 
>>> I am not certain whether you start with Java and end up with describing a 
>>> possible implementation for Go, or stay with Java. In any case Java is your 
>>> starting point. 
>>> 
>>> I guess, comparing any feature of any language, from the outside, then the 
>>> feature comparison lists turn up. But since you brought in Java..:
>>> 
>>> Then I can just as well throw in the JCSP library's Alternative (=ALT, 
>>> =select) class [1]. And here is their description of the associated 
>>> Alternative type:
>>> By invoking one of the following methods, a process may passively wait for 
>>> one or more of the guards associated with an Alternative object to become 
>>> ready. The methods differ in the way they choose which guard to select in 
>>> the case when two or more guards are ready:
>>> 
>>> select waits for one or more of the guards to become ready. If more than 
>>> one become ready, it makes an arbitrary choice between them (and 
>>> corresponds to the occam ALT).
>>> priSelect also waits for one or more of the guards to become ready. 
>>> However, if more than one becomes ready, it chooses the first one listed 
>>> (and corresponds to the occam PRI ALT). Note: the use of priSelect between 
>>> channel inputs and a skip guard (at lowest priority) gives us a polling 
>>> operation on the readiness of those channels.
>>> fairSelect also waits for one or more of the guards to become ready. If 
>>> more than one become ready, it prioritises its choice so that the guard it 
>>> chose the last time it was invoked has lowest priority this time. This 
>>> corresponds to a common occam idiom used for real-time applications. If 
>>> fairSelect is used in a loop, a ready guard has the guarantee that no other 
>>> guard will be serviced twice before it will be serviced. This enables an 
>>> upper bound on service times to be calculated and ensures that no ready 
>>> guard can be indefinitely starved.
>>> In that world Go would look like this (provided perhaps, it also supported 
>>> list type select guards):
>>> 
>>> select
>>> pri select
>>> fair select
>>> 
>>> [1] JCSP Alternative class - I am not certain how much JCSP has been used. 
>>> It's "beautiful" (my words). Observe that they didn't make any GoCSP 
>>> library..
>>> 
>>> ==
>>> Aside: After the above discussion in this thread I found what I searched 
>>> for, before I started it: a thread from 2012 [2]. Some déjà vu experience!
>>> 
>>> Is there any Go page with the rationale for having a single select type and 
>>> not the other select type(s)? Like [3] or [4]. If not, maybe a new 
>>> paragraph to [4]?
>>> 
>>> Øyvind
>>> 
>>> [2] Priority select in Go (2012)
>>> [3] Bell Labs and CSP Threads by Russ Cox
>>> [4] Why build concurrency on the ideas of CSP?
>>> ==
>>> 
 onsdag 12. mai 2021 kl. 16:52:19 UTC+2 skrev Haddock:
>> In addition to htq and ltq you have a third queue  into which you also 
>> insert a token once one has been added to htq or ltp. The 
>> thread/goroutine that serves htq, ltp, hq, lq is blocked by this 
>> additional queue. 

Re: [go-nuts] Still "missing" priority or ordered select in go?

2021-05-15 Thread Øyvind Teig
Thanks, rog. I appreciate this! Even if I cant' stop thinking that a "pri" 
would have been sligtly more elegant. But you shall be praised for the try! 
I wont' take the time to fine read the code, though... 

..Aside: Being more than busy to digest the fact that XMOS has announced a 
paradigm shift with keeping the xC compiler, but for new projects wanting 
us to code "in C" instead, with a library lib_xcore. There are reasons. But 
ordered select is kept! See my reaction blog note C plus lib_xcore 
black-boxes xC 

 (disclaimer: 
no association with XMOS, no ads, no income, no gifts etc with my blogs. 
Only fun an expensens)

torsdag 13. mai 2021 kl. 04:48:31 UTC+2 skrev ren...@ix.netcom.com:

> Here is a simple priority select implementation using unbuffered channels. 
> https://play.golang.org/p/Hvl0iMr-cFW 
> 
>
> Uncomment the lines as instructed and you will see that channel A is 
> always picked.
>
> What this demonstrates is that ‘priority’ and ‘event order’ is highly 
> dependent on latency, event frequency, etc. The ’sleep’ + locks in this 
> example function as an external clock - as long as all events are ready at 
> the clock edge you can implement priority - but with async events and 
> scheduling - priority is impossible.
>
> (In the absence of the sleep - the Go scheduler + OS scheduler determines 
> whether A or B will run and scheduling delays will allow B events to arrive 
> before an A event.
>
> You can also trivially change this example to implement the ‘close A, 
> close B’ scenario using a single Go routine and will see the desired ’never 
> ends’ state is obtained.
>
> (btw - there are probably some deadlock scenarios - I didn’t spend a lot 
> of time on this)
>
>
>
>
>
> On May 12, 2021, at 11:53 AM, Øyvind Teig  wrote:
>
> I am not certain whether you start with Java and end up with describing a 
> possible implementation for Go, or stay with Java. In any case Java is your 
> starting point. 
>
> I guess, comparing any feature of any language, from the outside, then the 
> feature comparison lists turn up. But since you brought in Java..:
>
> Then I can just as well throw in the JCSP library's Alternative (=ALT, 
> =select) class [1]. And here is their description of the associated 
> Alternative type:
>
> *By invoking one of the following methods, a process may passively wait 
> for one or more of the guards associated with an Alternative object to 
> become ready. The methods differ in the way they choose which guard to 
> select in the case when two or more guards are ready:*
>
>- *select 
>
> 
>  waits 
>for one or more of the guards to become ready. If more than one become 
>ready, it makes an arbitrary choice between them (and corresponds to 
>the occam ALT).*
>- *priSelect 
>
> 
>  also 
>waits for one or more of the guards to become ready. However, if more than 
>one becomes ready, it chooses the first one listed (and corresponds to 
>the occam PRI ALT). Note: the use of priSelect between channel inputs and 
> a 
>skip guard (at lowest priority) gives us a polling operation on 
>the readiness of those channels.*
>- *fairSelect 
>
> 
>  also 
>waits for one or more of the guards to become ready. If more than one 
>become ready, it prioritises its choice so that the guard it chose the 
> last 
>time it was invoked has lowest priority this time. This corresponds to a 
>common occam idiom used for real-time applications. If fairSelect is used 
>in a loop, a ready guard has the guarantee that no other guard will be 
>serviced twice before it will be serviced. This enables an upper bound on 
>service times to be calculated and ensures that no ready guard can be 
>indefinitely starved.*
>
> In that world Go would look like this (provided perhaps, it also supported 
> list type select guards):
>
> *select*
> *pri select*
> *fair select*
>
> [1] JCSP Alternative class 
> 
>  - 
> I am not certain how much JCSP has been used. It's "beautiful" (my words). 
> Observe that they didn't make any GoCSP library..
>
> *==*
> *Aside*: After the above discussion in this thread I found what I 
> searched for, before I started it: a thread from 2012 [2]. Some *déjà vu *
> experience!
>
> Is there any Go page with the rationale for having a single select type 
> and not the other select type(s)? Like [3] or [4]. If not, maybe a new 
> paragraph to [4]?
>
>