On Sunday, 17 July 2016 19:05:44 UTC+3, Scott Cotton wrote:
>
> Hi all,
>
> I'm looking for information/pointers for making the scheduling and 
> select {} choices determinisable for an application domain in which 
> non-determinism in scheduling/select causes problems.
>

This seems like queues are the wrong solution for communication in this 
case.

Just a simple case

ch := make(chan int)
go computeSquare(ch, 1)
go computeSquare(ch, 2)

fmt.Println(<-ch, <-ch)

Now, due to things running at different speeds, OS switching, and the 
inherent indeterminism in CPU, you can end up with either 1 or 4 as the 
output. Even if the Go scheduler does not interrupt, the OS or/and the CPU 
itself can cause the indeterminism.

The only reasonable way I can see this being solved is to introduce an 
order to the results.

ch1 := make(chan int)
ch2 := make(chan int)

go computeSquare(ch1, 1)
go computeSquare(ch2, 2)

fmt.Println(<-ch1, <-ch2)

Now there are different ways of approaching the ordering of intermediate 
results... and the nicest one will entirely depend on the problem at 
hand... But the basic premise is that, distribute the workload giving each 
process/thread/goroutine a token. Merge the results together you need to 
process the tokens in a particular order... *Of course each process in turn 
can split the work similarly. *But when you want to schedule new work e.g. 
a new iteration, all previous work must have been done. For random, you 
would need to also split your seed somehow...

e.g. the simplest thing that could work

var mu sync.Mutex
var results [8]struct {
done  bool
value int
}

for i := range results {
go func(index int){
result := index * index

mu.Lock()
results[index].value = result
results[index].done = true
mu.Unlock()
}(i)
}

*// alternatively you can also use here WaitGroup to wait that all 
computations have been completed.*

var total int
for i := range results {
var value int
for {
mu.Lock()
if results[i].done {
value = results[i].value
mu.Unlock()
break
}
mu.Unlock()
time.Sleep(time.Millisecond)
}

total = (total << 1) | value
}

fmt.Println(total)

*tl;dr; don't use queues for communicating results from different 
threads/goroutines/processes/computers.*

*+ Egon*


> For my own purposes I plan to make a determinisable version of the
> gc toolchain where one can set a random seed via an environmental variable.
> If there is shared interest in this endeavour, please chime in.
>
> If any gc officianados could comment about how to go about this (on 
> technical grounds, not contribution IP requirements), it would be 
> appreciated.
>
> Thanks,
>
> -- 
> Scott Cotton
> http://www.iri-labs.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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to