Page 2 of 2

Re: Inserter facing up/north slower than other directions

Posted: Wed May 24, 2017 4:34 pm
by joon
Nice, took 2 years but great. My ocd can finally rest in pieces.

Re: Inserter facing up/north slower than other directions

Posted: Wed May 24, 2017 5:39 pm
by Zulan
Twinsen wrote:The problem was a bit deeper. The vector given to the atan2 was rotated imprecisely.
First, awesome to get it fixed now!

So I'm curious. Is this in any way related to the odd shape that the inserter hand follows?
inserters.png
inserters.png (33.45 KiB) Viewed 7920 times
These are the positions a freshly placed fast inserter follows when transferring chest-to-chest as per held_stack_position. All of them rotated such that source chest is on the bottom, target chest on the top.

In any case, are you just trying to increase accuracy or are you also accepting and dealing with the eventual inaccuracies of floating point?

Re: Inserter facing up/north slower than other directions

Posted: Wed May 24, 2017 6:32 pm
by Twinsen
I'm not sure why the inserter moves so oddly. Most of it's behavior code is probably there since version 0.1 so probably not even the guy who wrote it(kovarex) would know why.
Zulan wrote:In any case, are you just trying to increase accuracy or are you also accepting and dealing with the eventual inaccuracies of floating point?
I don't understand the question.
Most of the inaccuracies(and probably the silly inserter behavior) are from our custom trigonometrical functions which have to be both fast and deterministic. Floating point inaccuracies are not a problem.

Re: Inserter facing up/north slower than other directions

Posted: Wed May 24, 2017 7:19 pm
by Zulan
Twinsen wrote:I'm not sure why the inserter moves so oddly. Most of it's behavior code is probably there since version 0.1 so probably not even the guy who wrote it(kovarex) would know why.
Zulan wrote:In any case, are you just trying to increase accuracy or are you also accepting and dealing with the eventual inaccuracies of floating point?
I don't understand the question.
Most of the inaccuracies(and probably the silly inserter behavior) are from our custom trigonometrical functions which have to be both fast and deterministic. Floating point inaccuracies are not a problem.
It is widely recognized that comparing two floating point numbers via == is bad. I don't think I could explain it better than this FAQ entry. I believe this applies here, despite any additional contributing factors to inaccuracy that may have been fixed now.

Re: Inserter facing up/north slower than other directions

Posted: Wed May 24, 2017 7:24 pm
by Rseding91
Zulan wrote:
Twinsen wrote:I'm not sure why the inserter moves so oddly. Most of it's behavior code is probably there since version 0.1 so probably not even the guy who wrote it(kovarex) would know why.
Zulan wrote:In any case, are you just trying to increase accuracy or are you also accepting and dealing with the eventual inaccuracies of floating point?
I don't understand the question.
Most of the inaccuracies(and probably the silly inserter behavior) are from our custom trigonometrical functions which have to be both fast and deterministic. Floating point inaccuracies are not a problem.
It is widely recognized that comparing two floating point numbers via == is bad. I don't think I could explain it better than this FAQ entry. I believe this applies here, despite any additional contributing factors to inaccuracy.
Factorio requires determinism which means that if any of our compilers didn't produce the same results for floating point operations it would be an error so comparison via == is perfectly fine.

Re: Inserter facing up/north slower than other directions

Posted: Wed May 24, 2017 9:04 pm
by Zulan
Rseding91 wrote:
Zulan wrote: It is widely recognized that comparing two floating point numbers via == is bad. I don't think I could explain it better than this FAQ entry. I believe this applies here, despite any additional contributing factors to inaccuracy.
Factorio requires determinism which means that if any of our compilers didn't produce the same results for floating point operations it would be an error so comparison via == is perfectly fine.
These are two different things. Floating point math (without aggressive optimization) is both deterministic and approximate at the same time.
You can very well deterministically compute something that should mathematically be 0 is not == 0. That is not wrong with fp math. Just because it is deterministic, doesn't mean that some obscure change in the code / mod breaks it again in some other way that will make you scratch your head for years. I thought that very bug was a pretty good example of that.

Re: Inserter facing up/north slower than other directions

Posted: Wed May 24, 2017 11:46 pm
by IronCartographer
Zulan wrote:These are two different things. Floating point math (without aggressive optimization) is both deterministic and approximate at the same time.
You can very well deterministically compute something that should mathematically be 0 is not == 0. That is not wrong with fp math. Just because it is deterministic, doesn't mean that some obscure change in the code / mod breaks it again in some other way that will make you scratch your head for years. I thought that very bug was a pretty good example of that.
You're not wrong. However, with the level of optimization required for something as central as inserter mechanics, having to use rounding in every conditional check would have a significant impact on performance.

Re: Inserter facing up/north slower than other directions

Posted: Thu May 25, 2017 7:37 pm
by Zulan
IronCartographer wrote:
Zulan wrote:These are two different things. Floating point math (without aggressive optimization) is both deterministic and approximate at the same time.
You can very well deterministically compute something that should mathematically be 0 is not == 0. That is not wrong with fp math. Just because it is deterministic, doesn't mean that some obscure change in the code / mod breaks it again in some other way that will make you scratch your head for years. I thought that very bug was a pretty good example of that.
You're not wrong. However, with the level of optimization required for something as central as inserter mechanics, having to use rounding in every conditional check would have a significant impact on performance.
This is a good and important point - however two things:

1) To get a sense of impact, we are talking about a code that takes, for the lack of a better measurement, around 600 instructions* in the best case. Doing an approximate equals instead of a literal equals changes from 4 to 5 or 8 instructions depending on how careful you want to be. No additional jumps included. I highly doubt the difference could even measured with statistical significance.

2) A better approach would be to use fixed precision math, and mathematical model that doesn't need frequent trigonometric calculations, which has significant potential for performance improvement. But of course that has significant development cost and at this point I can't tell how much impact even that would have in the big picture.

That said, I get the point that this is a theoretical discussion and I understand the pragmatic approach of not touching it if it works fine. Primarily I'm happy it's fixed, but also I'm a bit curious :).

* Inserter::update: ~600 instructions for rotating with a full hand, ~900 instructions for rotating with an empty hand, and ~2500 instructions for picking up / dropping an item to/from a chest.

Re: Inserter facing up/north slower than other directions

Posted: Thu May 25, 2017 10:47 pm
by TwoD
Rseding91 wrote:
Zulan wrote:
Twinsen wrote:I'm not sure why the inserter moves so oddly. Most of it's behavior code is probably there since version 0.1 so probably not even the guy who wrote it(kovarex) would know why.
Zulan wrote:In any case, are you just trying to increase accuracy or are you also accepting and dealing with the eventual inaccuracies of floating point?
I don't understand the question.
Most of the inaccuracies(and probably the silly inserter behavior) are from our custom trigonometrical functions which have to be both fast and deterministic. Floating point inaccuracies are not a problem.
It is widely recognized that comparing two floating point numbers via == is bad. I don't think I could explain it better than this FAQ entry. I believe this applies here, despite any additional contributing factors to inaccuracy.
Factorio requires determinism which means that if any of our compilers didn't produce the same results for floating point operations it would be an error so comparison via == is perfectly fine.
Even if your compilers all produce the same comparison operation, different FP hardware executing it may not return the same result, which could probably lead to desyncs in MP.

Re: Inserter facing up/north slower than other directions

Posted: Thu May 25, 2017 11:20 pm
by Rseding91
TwoD wrote:Even if your compilers all produce the same comparison operation, different FP hardware executing it may not return the same result, which could probably lead to desyncs in MP.
Could, but so far hasn't. And with the sample size we have I'm 99.99% confident in saying they all produce the same result.

Re: Inserter facing up/north slower than other directions

Posted: Fri May 26, 2017 1:17 am
by BenSeidel
Rseding91 wrote:
TwoD wrote:Even if your compilers all produce the same comparison operation, different FP hardware executing it may not return the same result, which could probably lead to desyncs in MP.
Could, but so far hasn't. And with the sample size we have I'm 99.99% confident in saying they all produce the same result.
does anyone know an example of x86/x64 hardware (except with the Pentium bug) that would produce non IEEE floating point operation defined results? And I'm not talking about enhanced precision extensions etc, but hardware that simply does not allow for a correct IEEE mode.

Re: Inserter facing up/north slower than other directions

Posted: Fri May 26, 2017 5:08 am
by bbgun06
Are the inserters moving in odd paths because they're trying to look like they're moving in 3D perspective?

Re: Inserter facing up/north slower than other directions

Posted: Fri May 26, 2017 8:59 am
by TwoD
BenSeidel wrote:
Rseding91 wrote:
TwoD wrote:Even if your compilers all produce the same comparison operation, different FP hardware executing it may not return the same result, which could probably lead to desyncs in MP.
Could, but so far hasn't. And with the sample size we have I'm 99.99% confident in saying they all produce the same result.
does anyone know an example of x86/x64 hardware (except with the Pentium bug) that would produce non IEEE floating point operation defined results? And I'm not talking about enhanced precision extensions etc, but hardware that simply does not allow for a correct IEEE mode.
Yes, it's unlikely you'd find such cases, at least in machines produced around or after 2008 when the current version of the standard was made official. Factorio does seem to run well on quite dated hardware though. :)
https://stackoverflow.com/questions/223 ... e-ieee-754

I was a bit usure about my old AMD Phenom II machine, but running the paranoia testers from http://www.math.utah.edu/~beebe/software/ieee/
Floats are annoying, and even though HW differences are possible, I do agree they are unlikely to affect Factorio players.

Re: Inserter facing up/north slower than other directions

Posted: Fri May 26, 2017 11:29 am
by Zulan
TwoD wrote: Even if your compilers all produce the same comparison operation, different FP hardware executing it may not return the same result, which could probably lead to desyncs in MP.
It's not even unlikely, it's impossible. We're talking about x86-64, so there simply are no differences in how the hardware executes FP instructions. If there were, it would be a huge hardware bug.

Of course, Factorio is not at liberty to freely use unsafe fast-math compiler-optimizations. Another challenge might be portable choice of math libraries. For instance I don't know if there is any guarantee that std::sin always returns the exact same result for different implementations of the standard library.

Re: Inserter facing up/north slower than other directions

Posted: Fri May 26, 2017 12:00 pm
by posila
Zulan wrote:
TwoD wrote: Even if your compilers all produce the same comparison operation, different FP hardware executing it may not return the same result, which could probably lead to desyncs in MP.
It's not even unlikely, it's impossible. We're talking about x86-64, so there simply are no differences in how the hardware executes FP instructions. If there were, it would be a huge hardware bug.
Sometimes compilers behave in unexpected way. For example we had issue with MSVC 2015 not respecting type of primitive constexpr types: constexpr float noiseVariance = 0.28874039688617059; ...noiseValriance would be treated as double, so result of myFloat * noiseVariance would be double instead of expected float, and it this expression was used as function argument, overload for double would be called instead of one for float.

As for HW, we worry CPU flags which change how floating point operations are rounded. AFAIK the flags are global, so if any application changes them, it affects all applications on the system. Other than that results of instructions should be same on every x86-64 CPU.
Of course, Factorio is not at liberty to freely use unsafe fast-math compiler-optimizations. Another challenge might be portable choice of math libraries. For instance I don't know if there is any guarantee that std::sin always returns the exact same result for different implementations of the standard library.
Yeah, we have to be carefull with using std math functions, we use implementations from various places (randomly found on internet).

Re: Inserter facing up/north slower than other directions

Posted: Fri May 26, 2017 5:27 pm
by torne
posila wrote:As for HW, we worry CPU flags which change how floating point operations are rounded. AFAIK the flags are global, so if any application changes them, it affects all applications on the system. Other than that results of instructions should be same on every x86-64 CPU.
Rounding mode and other floating point control flags should be context-switched along with the rest of the floating point register state when switching threads. They're global from the *hardware's* point of view, but so are the actual floating point registers; it's up to the multitasking kernel to do the right thing here, and it'd be a kernel bug if this didn't happen.

Re: Inserter facing up/north slower than other directions

Posted: Fri May 26, 2017 11:11 pm
by Zulan
torne wrote:
posila wrote:As for HW, we worry CPU flags which change how floating point operations are rounded. AFAIK the flags are global, so if any application changes them, it affects all applications on the system. Other than that results of instructions should be same on every x86-64 CPU.
Rounding mode and other floating point control flags should be context-switched along with the rest of the floating point register state when switching threads. They're global from the *hardware's* point of view, but so are the actual floating point registers; it's up to the multitasking kernel to do the right thing here, and it'd be a kernel bug if this didn't happen.
Exactly. There's a lengthy article about the topic here: https://randomascii.wordpress.com/2013/ ... terminism/ - I think Factorio should be fine.

Kinda odd to say goodbye to this bug :geek:

Re: Inserter facing up/north slower than other directions

Posted: Sat May 27, 2017 4:42 am
by dgw
Funny, I was just musing that my advanced circuit line seemed to be imbalanced, and noted that there was much talk about inserters facing north having a speed penalty all over reddit, the wiki, the forums… Half of my adv. circuit assemblers face north, and half south…

I came looking for more info and I see that it's fixed as of today. If it's still imbalanced I'll have to find another scapegoat! (Yes, I've only had the game less than a week. Blaming an inserter bug was a great way to avoid having to blame myself for an inefficient layout, but I've lost that excuse! :P)

Re: Inserter facing up/north slower than other directions

Posted: Tue May 30, 2017 6:42 am
by Moosfet
Rseding91 wrote:
Zulan wrote:It is widely recognized that comparing two floating point numbers via == is bad. I don't think I could explain it better than this FAQ entry. I believe this applies here, despite any additional contributing factors to inaccuracy.
Factorio requires determinism which means that if any of our compilers didn't produce the same results for floating point operations it would be an error so comparison via == is perfectly fine.
It isn't about determinism. Try this:

Code: Select all

#include <stdio.h>

int main () {

  double a = 0.1;
  double b = 0.2;
  double c = 0.3;
  if (a + b == c) {
    printf("%f == %f\n", a + b, c);
  } else {
    printf("%f != %f\n", a + b, c);
  };
};
It is deterministic. It'll tell me that 0.300000 != 0.300000 every time I run it. It's only wrong because floating point numbers are approximations (doubles are merely better approximations than floats) and so it is a mistake to ask whether the results are exactly equal or exactly not equal because approximations are by definition not exact. Whatever "a + b" is, it is very close to whatever is in "c" (which also isn't exactly 0.3), but I didn't ask whether it was very close, I asked whether it was exactly the same, and it isn't.