On Friday, October 27, 2017 at 4:57:46 PM UTC-4, T L wrote: > > > > On Friday, October 27, 2017 at 4:51:15 PM UTC-4, Axel Wagner wrote: >> >> Yes. The random number generator employed (right above from what I linked >> to; the fastrand function), apparently, is unsurprisingly imperfect. >> > > Why not to maintain a global start index for each goroutine? > The value of the start index is the number of executed select blocks in a > goroutine. > So that we can change the fastrandn implementation to > "return uint32(uint64(fastrand() + current_g.numExecutedSelects) * uint64(n) > >> 32)" >
Aha, which function is unfair, fastrand or fastrandn? If fastrandn is unfair, then the above trick doesn't work. > > >> >> On Fri, Oct 27, 2017 at 10:47 PM, T L <tapi...@gmail.com> wrote: >> >>> It is also not uniform for powers of two. >>> If there a 8 cases, the sixth one will only get a 80% chance of the >>> first one. >>> >>> On Friday, October 27, 2017 at 4:33:47 PM UTC-4, Axel Wagner wrote: >>>> >>>> The code suggests, that select is indeed not fair: >>>> >>>> https://github.com/golang/go/blob/a4d03a9bf7604b727abd0a1ebfb118ff6366ee50/src/runtime/stubs.go#L109 >>>> Which seems fine to me. A fair, uniform PRNG for ranges that are not >>>> powers of two gets a fair bit of overhead and no program should depend on >>>> uniformity of select for correctness anyway. >>>> >>>> On Fri, Oct 27, 2017 at 10:28 PM, T L <tapi...@gmail.com> wrote: >>>> >>>>> It looks the distribution of the RNG results depends on the number of >>>>> cases. >>>>> The third case only gets the lowest possibility of there are 6 cases, >>>>> >>>>> >>>>> On Friday, October 27, 2017 at 4:21:12 PM UTC-4, T L wrote: >>>>>> >>>>>> A better example to show the inhomogeneity of the selected >>>>>> possibilities of each case. >>>>>> >>>>>> package main >>>>>> >>>>>> import "fmt" >>>>>> >>>>>> func main() { >>>>>> foo := make(chan struct{}) >>>>>> close(foo) >>>>>> var a, b, c, d, e, f, g float64 >>>>>> fa := func(){a++} >>>>>> fb := func(){b++} >>>>>> fc := func(){c++} >>>>>> fd := func(){d++} >>>>>> fe := func(){e++} >>>>>> ff := func(){f++} >>>>>> fg := func(){g++} >>>>>> for i := 0; i < 1000000; i++ { >>>>>> select { >>>>>> case <-foo: fa() >>>>>> case <-foo: fb() >>>>>> case <-foo: fc() >>>>>> case <-foo: fd() >>>>>> case <-foo: fe() >>>>>> case <-foo: ff() >>>>>> case <-foo: fg() >>>>>> } >>>>>> } >>>>>> fmt.Println(a/a) >>>>>> fmt.Println(b/a) >>>>>> fmt.Println(c/a) >>>>>> fmt.Println(d/a) >>>>>> fmt.Println(e/a) >>>>>> fmt.Println(f/a) >>>>>> fmt.Println(g/a) >>>>>> } >>>>>> >>>>>> result: >>>>>> >>>>>> 1 >>>>>> 0.9999052991869258 >>>>>> 0.9015652691532394 >>>>>> 0.9691884140319548 >>>>>> 0.966320332264567 >>>>>> 0.9669020658305938 >>>>>> 0.9604624105415533 >>>>>> >>>>>> On Friday, October 27, 2017 at 4:08:39 PM UTC-4, T L wrote: >>>>>>> >>>>>>> The following program constantly prints a value larger than 1.02 >>>>>>> >>>>>>> package main >>>>>>> >>>>>>> import "fmt" >>>>>>> >>>>>>> func main() { >>>>>>> foo, bar := make(chan struct{}), make(chan struct{}) >>>>>>> close(foo) >>>>>>> close(bar) >>>>>>> x, y := 0.0, 0.0 >>>>>>> f := func(){x++} >>>>>>> g := func(){y++} >>>>>>> for i := 0; i < 1000000; i++ { >>>>>>> select { >>>>>>> case <-bar: g() >>>>>>> case <-foo: f() >>>>>>> case <-bar: g() >>>>>>> case <-foo: f() >>>>>>> case <-bar: g() >>>>>>> case <-foo: f() >>>>>>> } >>>>>>> } >>>>>>> fmt.Println(x/y) >>>>>>> } >>>>>>> >>>>>>> if the last two cases are removed, then it becomes quit fair. >>>>>>> >>>>>> -- >>>>> 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. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> -- >>> 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. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- 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.