-
Notifications
You must be signed in to change notification settings - Fork 158
FIX: CBA_missionTime time leak #1320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Above to 6e5, some precision error appearing randomly. This commit exit the addition of CBA_missionTime when a precision error occure and don't actualise the GVAR(lastTickTime) to not lost this time.
|
What does I don't understand what you mean by "leak", but I haven't tried your debug code for now. |
Don't know how to call it but in the PR it contain
Basically |
|
So instead of adding small deltas of time we want the delta to grow enough to make a difference? |
|
Yes |
|
Hmm, that has its own imprecissions. I was thinking about incorporating |
Agree, the imprecision with this implementation is less than a second which is enough for us I think.
I saw it but didn't find a clever use of it or we need to design this thing way differently
I also think about it. Like you store But computer scientist should already design something to deal with this, isn't it? We could also store the big part of the number in a variable and the small part in an other: |
They'd just use doubles instead of single floats and be done with it. We're stuck with singles. By using strings, I attempt to get the same benefit as doubles by changing data type. Maybe we could also use some array [a,b], where b is the last 6 digits of the mission time and a is the number of millions. |
I like this idea but the imprecision start at 1e5 because we are summing to it 1e-2 number |
|
[10,000,000] |
|
If we use 3D array, we can use vector operation. |
|
lol sure |
|
Here is an example of addition without imprecision until 1e9 (theoretical). removeMissionEventHandler ["EachFrame", v];
Vdofin_somme = 0;
Vdofin_start = 6e5;
Vdofin_missionTime = [
floor((Vdofin_start % 1e9)/1e6),
floor((Vdofin_start % 1e6)/1e3),
Vdofin_start % 1e3
];
Vdofin_lastTickTime = diag_tickTime;
v = addMissionEventHandler ["EachFrame", {
private _tickTime = diag_tickTime;
Vdofin_somme = Vdofin_somme + _tickTime - Vdofin_lastTickTime;
Vdofin_missionTime = Vdofin_missionTime vectorAdd [0, 0, _tickTime - Vdofin_lastTickTime];
if (selectMax Vdofin_missionTime > 1000) then {
private _limitReach = Vdofin_missionTime findIf {_x > 1000};
private _diff = [0, 0, 0];
_diff set [_limitReach, -1000];
_diff set [_limitReach - 1, 1];
Vdofin_missionTime = Vdofin_missionTime vectorAdd _diff;
};
Vdofin_lastTickTime = _tickTime;
}];Watch in debug, the different is null: The commit is a prof of concept. May be it is a too big hammer |
|
So, if this concept is fine for the CBA Team (?) Note: _timeVector = [
floor((_time % 1e9)/1e6),
floor((_time % 1e6)/1e3),
time % 1e3
];Convert vector time to positive or negative time (R): _timeVector vectorDotProduct [1e6 , 1e3, 1]Addition of two vector time: _timeVector1 vectorAdd _timeVector2Difference of two vector time: _timeVector1 vectorDiff _timeVector2Comparison of vector time, test if _timeVector1 > _timeVector2: private _timeDiff = [_timeVector1 , _timeVector2];
_timeDiff sort false;
_timeDiff#0 isEqualTo _timeVector1; |
|
Turning This implementation feels goofy. Will have to think about this some more. |
I know, that why I said:
|
|
I'm still in favour of using a string to store this non-single float. |
|
With vector representation we have more engine method: #1320 (comment) |
|
You'd have to change the string covering the >1000 digits only once every 1000 seconds=16,67 minutes. Performance is irrelevant. |
I don't see a string approach without imprecision when doing addition, substation, comparison and What is your idea? |
|
see #1323 |
|
See #1324 |
For
CBA_missionTimeabove to 6e5s (7 days):Addition with
CBA_missionTimehas some floating point precision error appearing randomly. This can be see thanks to this code mimicking the actual CBA behaviour:Check in debug console the leak happening after a few second:
Vdofin_somme + Vdofin_start - Vdofin_missionTimeThis leak is due to the problem that
_tickTime - GVAR(lastTickTime)is around 0.01 to 0.1 which is between 1e6 to 1e7 power of magnitude smaller thanCBA_missionTime. So when_tickTime - GVAR(lastTickTime)is added to 6e5 the result is the same as before the addition.The idea is to wait until
_tickTime - GVAR(lastTickTime)is higher. To do so, first we need to check if a floating point error occur and don't updateCBA_missionTimeANDGVAR(lastTickTime). So the_tickTime - GVAR(lastTickTime)will get higher and higher until the floating point error do not occur any more.For the previous code this mean this:
For CBA, see commits.
This allow dedicated server with CBA work longer than 5e5s and lower than 1e6s without significant time leak.
When merged this pull request will:
CBA_missionTimeabove to 6e5s (7 days) and lower than 1e6s (11.5 days).CBA_missionTime + (_tickTime - GVAR(lastTickTime))is equal to thanCBA_missionTimeGVAR(lastTickTime)CBA_missionTimeandGVAR(lastTickTime)