4 replaced http://stackoverflow.com/ with https://stackoverflow.com/
source | link

Inspired by your post on StackOverflowyour post on StackOverflow, I've just started implementing a 32 bit floating-point type in software and the results are promising.

Inspired by your post on StackOverflow, I've just started implementing a 32 bit floating-point type in software and the results are promising.

Inspired by your post on StackOverflow, I've just started implementing a 32 bit floating-point type in software and the results are promising.

3 added 105 characters in body
source | link
  • The same native assembly code is most likely deterministic provided you're careful with floating point flags and compiler settings.
  • There was one open source RTS project that claimed they got deterministic C/C++ compiles across different compilers using a wrapper library. I didn't verify that claim. (If I recall correctly it was about the STREFLOP library)
  • The .net JIT is allowed quite a bit of leeway. In particular it is allowed to use higher accuracy than requires. Also it uses different instruction sets on x86 and AMD64 (I think on x86 it uses the x87, AMD64 it uses some SSE instructions whose behavior differs for denorms).
  • Complex instructions (including trigonometric function, exponentials, logarithms) are especially problematic.
  1. Implement FixedPoint32 in C#. While this is not too hard(I have a half finished implementation) the very small range of values makes it annoying to use. You have to be careful at all times so you neither overflow, nor lose too much precision. In the end I found this not easier than using integers directly.
  2. Implement FixedPoint64FixedPoint64 in C#. I found this rather hard to do. For some operations intermediate integers of 128bit would be useful. But .net doesn't offer such a type.
  3. Use native code for the math operations which is deterministic on one platform. Incurs the overhead of a delegate call on every math operation. Loses ability to run cross platform.
  4. Use Decimal. But it's slow, takes a lot of memory and easily throws exceptions (division by 0, overflows). It's very nice for financial use, but no good fit for games.
  5. Implement a custom 32 bit floating-point. Sounded rather difficult at first. The lack of a BitScanReverse intrinsic causes a few annoyances when implementing this.
  • The same native assembly code is most likely deterministic provided you're careful with floating point flags and compiler settings.
  • There was one open source RTS project that claimed they got deterministic C/C++ compiles across different compilers using a wrapper library. I didn't verify that claim.
  • The .net JIT is allowed quite a bit of leeway. In particular it is allowed to use higher accuracy than requires. Also it uses different instruction sets on x86 and AMD64.
  • Complex instructions (including trigonometric function, exponentials, logarithms) are especially problematic.
  1. Implement FixedPoint32 in C#. While this is not too hard(I have a half finished implementation) the very small range of values makes it annoying to use. You have to be careful at all times so you neither overflow, nor lose too much precision. In the end I found this not easier than using integers directly.
  2. Implement FixedPoint64 in C#. I found this rather hard to do. For some operations intermediate integers of 128bit would be useful. But .net doesn't offer such a type.
  3. Use native code for the math operations which is deterministic on one platform. Incurs the overhead of a delegate call on every math operation. Loses ability to run cross platform.
  4. Use Decimal. But it's slow, takes a lot of memory and easily throws exceptions (division by 0, overflows). It's very nice for financial use, but no good fit for games.
  5. Implement a custom 32 bit floating-point. Sounded rather difficult at first. The lack of a BitScanReverse intrinsic causes a few annoyances when implementing this.
  • The same native assembly code is most likely deterministic provided you're careful with floating point flags and compiler settings.
  • There was one open source RTS project that claimed they got deterministic C/C++ compiles across different compilers using a wrapper library. I didn't verify that claim. (If I recall correctly it was about the STREFLOP library)
  • The .net JIT is allowed quite a bit of leeway. In particular it is allowed to use higher accuracy than requires. Also it uses different instruction sets on x86 and AMD64 (I think on x86 it uses the x87, AMD64 it uses some SSE instructions whose behavior differs for denorms).
  • Complex instructions (including trigonometric function, exponentials, logarithms) are especially problematic.
  1. Implement FixedPoint32 in C#. While this is not too hard(I have a half finished implementation) the very small range of values makes it annoying to use. You have to be careful at all times so you neither overflow, nor lose too much precision. In the end I found this not easier than using integers directly.
  2. Implement FixedPoint64 in C#. I found this rather hard to do. For some operations intermediate integers of 128bit would be useful. But .net doesn't offer such a type.
  3. Use native code for the math operations which is deterministic on one platform. Incurs the overhead of a delegate call on every math operation. Loses ability to run cross platform.
  4. Use Decimal. But it's slow, takes a lot of memory and easily throws exceptions (division by 0, overflows). It's very nice for financial use, but no good fit for games.
  5. Implement a custom 32 bit floating-point. Sounded rather difficult at first. The lack of a BitScanReverse intrinsic causes a few annoyances when implementing this.
2 added 113 characters in body
source | link
  • The same native assembly code is most likely deterministic provided you're careful with floating point flags and compiler settings.
  • There was one open source RTS project that claimed they got deterministic C/C++ compiles across different compilers using a wrapper library. I didn't verify that claim.
  • The .net JIT is allowed quite a bit of leeway. In particular it is allowed to use higher accuracy than requires. Also it uses different instruction sets on x86 and AMD64.
  • Complex instructions (including trigonometric function, exponentials, logarithms) are especially problematic.
  • iterating over a Dictionary<TKey,TValue> or HashSet<T> returns the elements in an undefined order.
  • object.GetHashCode() differs from run to run.
  • The implementation of the built in Random class is unspecified, use your own.
  • Multithreading with naive locking leads to reordering and differing results. Be very careful to use threads correctly.
  • When WeakReferences lose their target is indeterministic because the GC may run at any time.
  • The same native assembly code is most likely deterministic provided you're careful with floating point flags and compiler settings.
  • There was one open source RTS project that claimed they got deterministic C/C++ compiles across different compilers using a wrapper library. I didn't verify that claim.
  • The .net JIT is allowed quite a bit of leeway. In particular it is allowed to use higher accuracy than requires. Also it uses different instruction sets on x86 and AMD64.
  • iterating over a Dictionary<TKey,TValue> or HashSet<T> returns the elements in an undefined order.
  • object.GetHashCode() differs from run to run.
  • The implementation of the built in Random class is unspecified, use your own.
  • Multithreading with naive locking leads to reordering and differing results. Be very careful to use threads correctly.
  • The same native assembly code is most likely deterministic provided you're careful with floating point flags and compiler settings.
  • There was one open source RTS project that claimed they got deterministic C/C++ compiles across different compilers using a wrapper library. I didn't verify that claim.
  • The .net JIT is allowed quite a bit of leeway. In particular it is allowed to use higher accuracy than requires. Also it uses different instruction sets on x86 and AMD64.
  • Complex instructions (including trigonometric function, exponentials, logarithms) are especially problematic.
  • iterating over a Dictionary<TKey,TValue> or HashSet<T> returns the elements in an undefined order.
  • object.GetHashCode() differs from run to run.
  • The implementation of the built in Random class is unspecified, use your own.
  • Multithreading with naive locking leads to reordering and differing results. Be very careful to use threads correctly.
  • When WeakReferences lose their target is indeterministic because the GC may run at any time.
1
source | link