What is the most efficient way to run cross-platform deterministic simulations in Haskell?

My goal is to run a simulation that requires non-integer numbers on different machines, which may have different architectures and processor OSs. The main priority is that with the same initial state, each machine should reproduce the simulation in exactly the same way. The secondary priority is that I would like the calculations to have performance and accuracy as much as possible to swim with double precision.

As far as I can tell, there is no way to influence the determinism of floating point calculations from the Haskell program, similar to the _controlfp and _FPU_SETCW in C. So, at the moment, I consider my parameters

One problem with fixed point arithmetic libraries is that they do not, for example. trigonometric functions or the logarithms defined for them (because they do not implement a class of type Floating ), so I assume that I will need to provide lookup tables for all functions in the semantic data of the simulation. Or is there a better way?

Both fixed-point libraries also hide the newtype constructor, so any (maladaptation) serialization should be done using toRational / fromRational , as far as I can tell, and it looks like it will add unnecessary overhead.

My next step is to compare different fixed-point solutions to see the real world performance, but in the meantime, I am happy to accept any advice on this.

+6
source share
1 answer

Section 11 of the IEEE 754-2008 standard describes what is needed for reproducible floating point results. Among other things, you need unambiguous rules for evaluating an expression. Some languages ​​allow you to calculate floating point expressions with extra precision or allow some changes to expressions (for example, evaluate a*b+c in one command instead of separate multiply and add commands). I do not know about Haskell semantics. If Haskell does not accurately display expressions for certain floating point operations, then it cannot support reproducible floating point results.

Also, since you mention trigonometric and logarithmic functions, keep in mind that they differ from implementation to implementation. I do not know of any mathematical library that provides correctly rounded implementations of each standard mathematical function. ( CRLibm is the project for creating it.) Thus, each math library uses its own approximations, and their results are slightly different. Perhaps you can work around this by including a math library with your simulation code so that it is used instead of each default library for the Haskell implementation.

Routines that convert between binary floating point and decimal numbers are also the source of differences between implementations. This is less of a problem than before, since algorithms for correct conversion are known. However, this is something that may need to be checked in each implementation.

+7
source

Source: https://habr.com/ru/post/944950/


All Articles