Inserter facing up/north slower than other directions
Re: Inserter facing up/north slower than other directions
Nice, took 2 years but great. My ocd can finally rest in pieces.
Re: Inserter facing up/north slower than other directions
First, awesome to get it fixed now!Twinsen wrote:The problem was a bit deeper. The vector given to the atan2 was rotated imprecisely.
So I'm curious. Is this in any way related to the odd shape that the inserter hand follows?
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
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.
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.
I don't understand the question.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?
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
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.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.
I don't understand the question.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?
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.
Last edited by Zulan on Wed May 24, 2017 9:16 pm, edited 1 time in total.
Re: Inserter facing up/north slower than other directions
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.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.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.
I don't understand the question.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?
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.
If you want to get ahold of me I'm almost always on Discord.
Re: Inserter facing up/north slower than other directions
These are two different things. Floating point math (without aggressive optimization) is both deterministic and approximate at the same time.Rseding91 wrote: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.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.
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.
-
- Filter Inserter
- Posts: 464
- Joined: Tue Jun 28, 2016 2:07 pm
- Contact:
Re: Inserter facing up/north slower than other directions
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 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.
Re: Inserter facing up/north slower than other directions
This is a good and important point - however two things:IronCartographer wrote: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 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.
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
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 wrote: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.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.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.
I don't understand the question.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?
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
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.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.
If you want to get ahold of me I'm almost always on Discord.
Re: Inserter facing up/north slower than other directions
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.Rseding91 wrote: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.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.
Re: Inserter facing up/north slower than other directions
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
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.BenSeidel wrote: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.Rseding91 wrote: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.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.
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
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.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.
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
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.Zulan wrote: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.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.
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.
Yeah, we have to be carefull with using std math functions, we use implementations from various places (randomly found on internet).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
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.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.
Re: Inserter facing up/north slower than other directions
Exactly. There's a lengthy article about the topic here: https://randomascii.wordpress.com/2013/ ... terminism/ - I think Factorio should be fine.torne wrote: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.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.
Kinda odd to say goodbye to this bug
Re: Inserter facing up/north slower than other directions
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! )
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! )
Re: Inserter facing up/north slower than other directions
It isn't about determinism. Try this:Rseding91 wrote: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.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.
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);
};
};