I think a little more background about the context of the question would be 
helpful. Determinism may mean different things in different situations 
depending ont he guarantees you need. Also, did you know that the go 
playground (play.golang.org) is intended to be generally deterministic so 
that output can be cached? That might be a good place for you to start. I 
have a few more general thoughts:

Is the code trusted or could it be "attacker" controller? There are going 
to be a lot of random execution delay differences on a modern 
multiprocessor, and they'd be noticeable to a goroutine calling time.Sleep 
in a loop especially if the program was not the only application on the 
physical host. Theoretically, you could use this as a random number 
generator and cause non-deterministic execution, but obviously that code 
would be quite weird and probably wouldn't make it past code review. But if 
the code is untrusted, you may have to worry about it.

Another thought is that goroutine scheduling is effectively 
non-deterministic on a multiprocessor (I don't know enough about the 
runtime to say whether this is true on a uniprocessor), so the runtime's 
scheduling algorithm (plus natural delays I mentioned above) can cause 
non-determinism to emerge. For example, depending on goroutine scheduling 
order, this code may sometimes crash: https://go.dev/play/p/lEZEAYdji-f . 
As Axel said you will need to run it locally, the playground results may be 
cached iirc. I ran it 100 times and it crashed 9 times. This code is 
contrived, but in a large system this sort of non-determinism may still 
happen due to the general complexity of it all, and it may or may not 
matter to you.

Also, what exactly do you mean by "determinism"? Another example: if you 
create many goroutines in a loop and have them all do an atomic.AddInt64 on 
a shared variable (e.g. for them to get a global ID for themselves), the 
specific number each goroutine is assigned will essentially be random. The 
numbers will not form a continuous distribution, but they will be random at 
least in some sense on a multiprocessor. If the code does different things 
based on a combination of this kind of simple non-determinism, it can cause 
different code paths and different specific interleaving of the code in 
different executions. But, in practice it there may not be an observable 
effect in your average program, so I don't know if you consider this aspect 
important.

-Kevin

On Saturday, January 14, 2023 at 4:38:18 PM UTC-7 axel.wa...@googlemail.com 
wrote:

> Oh, also, fmt: https://go.dev/play/p/xxOw3vqWR4u (probably need to run 
> this offline)
>
> Honestly, I don't think there really is a practical way to prevent 
> non-determinism without severly hampering the language. Your best bet is 
> probably to compile a program to webassembly and then don't give the VM 
> access to any source of entropy.
>
> On Sun, Jan 15, 2023 at 12:29 AM Axel Wagner <axel.wa...@googlemail.com> 
> wrote:
>
>> There's also maps, select and goroutines in general. Funnily enough I 
>> blogged about this some years ago, for fun 
>> <https://blog.merovius.de/posts/2018-01-15-generating_entropy_without_imports_in_go/>
>> .
>>
>> On Sat, Jan 14, 2023 at 11:52 PM Stan Srednyak <stan....@gmail.com> 
>> wrote:
>>
>>> How much of Golang functionality must be excluded in order to guarantee 
>>> deterministic execution on a fixed system?
>>>
>>> There are typical sources of nondeterminism
>>>
>>> 1. /dev/urandom 
>>>
>>> 2. time 
>>>
>>> We should include system variables here, but lets suppose we fix the 
>>> system. 
>>>
>>> One more source could be system files. Lets say we use chroot to jail 
>>> the process. This should be done carefully: naive use does not exclude 
>>> /dev/urandom , and as a result e.g. RSA key generation has access to 
>>> randomness. But lets assume that we dealt with this issue.
>>>
>>>
>>> Also, the stack can be a source of randomness. In Golang, it is possible 
>>> to get info about the stack. But lets say, we blocked these possibilities 
>>> by forbidding the access to runtime.
>>>
>>> What else is there?
>>>
>>> At the moment it seems that to guarantee deterministic execution it is 
>>> necessary to block access to modules:
>>> runtime 
>>> syscall
>>> time 
>>> crypto -- the parts that have to do with key generation
>>> os -- parts that get system variables and process information
>>> math/rand
>>>
>>> Which other standard modules can give rise to nondeterminism?
>>>
>>> It seems that modules 
>>> -ioutil
>>> -bufio
>>> -most of os
>>> -strings
>>> -bytes
>>>
>>> are "nondeterminism safe".
>>>
>>> File info can be a source of nondeterminism - the last access time in 
>>> nanoseconds.
>>>
>>>
>>>
>>> -- 
>>> 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/731a9430-6c0d-4f9f-87ec-75f833cc544fn%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/golang-nuts/731a9430-6c0d-4f9f-87ec-75f833cc544fn%40googlegroups.com?utm_medium=email&utm_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/a304c06c-a55f-43e8-83b5-68524f689fcen%40googlegroups.com.

Reply via email to