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.