Deterministic select in Golang


Go cannot implement a “deterministic” select without limiting ordering semantics, which can have a negative impact on performance.

The realization that there is no objective ordering for things can be mind-boggling for someone who is accustomed to living at human scales and has, as a result, never had to deal with relativity being a real thing. However, because computers run fast enough, you are forced to face the reality that there is no objective ordering for things.

It is best practice in programming to pretend that two threads that do not synchronize simply have an undefined ordering relationship between them until such time as they synchronize themselves explicitly. In this situation, it is not accurate to say that “Oh, there is a real order, but we’re just pretending that there’s no real order” because, in all actuality, there is no real order. When operating at full capacity, the processing speeds of today’s central processing units (CPUs) and hardware are close enough to that of light to create situations in which there is no objectively valid “first thing that happened.” This is because the speeds at which they operate are comparable to those of light. The rest of the time, even if there is an objectively true order in relativistic terms, the cost of determining that order can easily significantly exceed the cost of anything else that is going on.

It is not a valid opinion to hold within a select statement that this statement “must” come before some other statement, unless you have explicitly synchronized to guarantee that is the case. In that case, you probably don’t want one all-encompassing select statement anyway, but rather a sequence of statements of some kind. If you do not explicitly synchronize to guarantee that is the case, it is not a valid opinion to hold within a select statement.

It is wonderful that non-determinism can be helpful in any way, but even if Go were to implement a “deterministic” select in code somehow, it would still be non-deterministic with anything that resembles current Go semantics. This is because even if it were deterministic to the runtime, it would still be nondeterministic at the level that the Go programmer is working at. This is because even if it were deterministic to the runtime, it would still be nondeterministic. To put it another way, it is not really possible because there is no way to do so without severely limiting ordering semantics, which would have a significant negative impact on performance.

If you want to be programming in a manner that is multithreaded, you will basically need to give up that kind of determinism in order to do so. It’s not just Go; this direction is being taken in every aspect of computing, from programming languages to physical hardware. The imposition of determinism on the universe would be financially prohibitive, and the speed at which our computers process information is such that relativity would render it essentially impossible even if it were possible. (This is especially true when working across networks, but even when working with multiple sockets on a single CPU, you can run into issues with relativity and absolute ordering.)