Inserter facing up/north slower than other directions

This subforum contains all the issues which we already resolved.
joon
Fast Inserter
Fast Inserter
Posts: 131
Joined: Mon Jan 19, 2015 7:11 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post by joon »

Nice, took 2 years but great. My ocd can finally rest in pieces.

Zulan
Long Handed Inserter
Long Handed Inserter
Posts: 52
Joined: Mon Jan 25, 2016 5:55 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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 7773 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?

Twinsen
Factorio Staff
Factorio Staff
Posts: 1329
Joined: Tue Sep 23, 2014 7:10 am
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

Zulan
Long Handed Inserter
Long Handed Inserter
Posts: 52
Joined: Mon Jan 25, 2016 5:55 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.
Last edited by Zulan on Wed May 24, 2017 9:16 pm, edited 1 time in total.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13171
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.
If you want to get ahold of me I'm almost always on Discord.

Zulan
Long Handed Inserter
Long Handed Inserter
Posts: 52
Joined: Mon Jan 25, 2016 5:55 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

IronCartographer
Filter Inserter
Filter Inserter
Posts: 454
Joined: Tue Jun 28, 2016 2:07 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

Zulan
Long Handed Inserter
Long Handed Inserter
Posts: 52
Joined: Mon Jan 25, 2016 5:55 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

TwoD
Burner Inserter
Burner Inserter
Posts: 7
Joined: Thu May 25, 2017 10:43 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13171
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.
If you want to get ahold of me I'm almost always on Discord.

BenSeidel
Filter Inserter
Filter Inserter
Posts: 584
Joined: Tue Jun 28, 2016 1:44 am
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

bbgun06
Long Handed Inserter
Long Handed Inserter
Posts: 60
Joined: Fri Mar 27, 2015 4:09 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post by bbgun06 »

Are the inserters moving in odd paths because they're trying to look like they're moving in 3D perspective?

TwoD
Burner Inserter
Burner Inserter
Posts: 7
Joined: Thu May 25, 2017 10:43 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

Zulan
Long Handed Inserter
Long Handed Inserter
Posts: 52
Joined: Mon Jan 25, 2016 5:55 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

posila
Factorio Staff
Factorio Staff
Posts: 5201
Joined: Thu Jun 11, 2015 1:35 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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).

torne
Filter Inserter
Filter Inserter
Posts: 341
Joined: Sun Jan 01, 2017 11:54 am
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

Zulan
Long Handed Inserter
Long Handed Inserter
Posts: 52
Joined: Mon Jan 25, 2016 5:55 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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:

dgw
Fast Inserter
Fast Inserter
Posts: 197
Joined: Tue Apr 12, 2016 7:06 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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)

Moosfet
Long Handed Inserter
Long Handed Inserter
Posts: 64
Joined: Fri Jun 10, 2016 1:50 pm
Contact:

Re: Inserter facing up/north slower than other directions

Post 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.

Post Reply

Return to “Resolved Problems and Bugs”