Yes, the problem is fixed totally on tip.
The tip is using the normal mod operation "fastrand() % n".


On Friday, October 27, 2017 at 5:17:53 PM UTC-4, Axel Wagner wrote:
>
> It turns out that, apparently, at least on tip (what I linked to) the 
> fastrand implementation itself is actually pretty good. You might want to 
> re-run the test on tip. fastrandn will still be somewhat biased.
>
> On Fri, Oct 27, 2017 at 11:05 PM, Axel Wagner <axel.wa...@googlemail.com 
> <javascript:>> wrote:
>
>> Neither. fastrand is not a perfect PRNG, as that doesn't exist (much less 
>> in…fast) and the reduction is biased (necessarily, unless you are going to 
>> resort to rejection sampling, which is slow).
>>
>> On Fri, Oct 27, 2017 at 11:00 PM, T L <tapi...@gmail.com <javascript:>> 
>> wrote:
>>
>>>
>>>
>>> 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...@googlegroups.com <javascript:>.
>>> 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.

Reply via email to