• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

TriggerExecute init-inflation

Status
Not open for further replies.
Level 26
Joined
Aug 18, 2009
Messages
4,097
Just wondered why http://peeeq.de/code.php?id=6908 takes >90 seconds on the first run and additional runs only 16 to 17 seconds.

It appears that simultaneous TriggerExecute calls, i.e. this covers being within subthreads or event-firing too, stack up to init a data structure. So the first execution time for 1000x TriggerExecute is higher than if you were to split it up. Afterwards, you can run up to 1000x TriggerExecute without init costs. Only if you exceed the previous limit does it require more.

I do not know if that cache is cleared at some point, while not, it would take memory and for me, 15mio calls were enough to burst the bubble and make wc3 run out of memory.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Try using a different map, it might be the models or abilities are getting cached at the initial loading of a map.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Even without the output, I feel confident in my loose perception of time, to distinguish 17 seconds from 95.

@chobibo: The map is empty. There is nothing else running or influenced by that. I have tried what I stated above to exceed the limit further times to see it still needing the init difference. The effect would mean that inserting 0-TriggerSleepActions like every 1000th iteration (the outer loop) should be faster than having all 15000 in one go, which I could also confirm.

Just copy the code and try for yourself.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
No, I meant warcraft might be caching data for first use regardless of the map being loaded, that's why I suggested you test a different map the first time, and conduct the actual test the second time onwards.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Another map will hardly have such a scenario, so I restarted the same map instead (still being the same game session) after having triggered once. It required to init again.

Edit: Also funny thing: When you restart the map, the preload logger is still active and PreloadGenEnd will then list all the files wc3 loads on the map.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
After a few seconds via chat input to try different amounts. It works like this:

Code:
int execCount = 0;
int maxExecCount = 0;

void TriggerExecute(trigger t){
    execCount++

    if (execCount > maxExecCount){
        for (int i = maxExecCount + 1;i <= execCount;i++){
            //do init stuff
        }

        maxExecCount = execCount;
    }
}

*void onNewGameTick(){
    execCount = 0;
}

TaskManager agrees, memory stress for 1000*100 climbs up by ~460k and stays there afterwards. Running it again rises less and bounces back to that value.
No, I could not observe that behavior with TriggerEvaluate.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Read again. You can run a trigger any amount of times during a game. The memory won't increase from repeating. But if you execute too many triggers at once, at the same game tick, the game will statically claim space for the max amount of triggers you have run at a game tick. So you should either not run too many at once or maybe preload it, so execution later on becomes faster. Anyway, TriggerEvaluate > TriggerExecute. TriggerEvaluate does not even seem to be temporarily request memory and it's faster in either case.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
I got it now, the memory is tied with the trigger execute, sorry about earlier. I wonder why, can't be just because of waits...
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
And what if you execute X triggers one time with the same action code, instead of the same trigger X times ?

Also with that Preload exploit, you can write any string in a file, included not litteral ones (variables), right ?
If so, i have an other test to suggerate.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
JASS:
function a takes nothing returns nothing
    set udg_c=udg_c+1
    call Preload(I2S(udg_c))
    call PreloadGenEnd("recur.txt")
    call TriggerExecute(udg_t)
endfunction

function b takes nothing returns nothing
    set udg_c=0
    set udg_t=CreateTrigger()
    call TriggerAddAction(udg_t, function a)
    call a()
endfunction

1308, with evaluate 1734. Do not ask me what this depends on. At least not from the stress in the function.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
I am not quite sure if it relates to it but I did some tests concerning the clearance of associated events on DestroyTrigger(). The memory release only worked or only worked wholly if there were not too many events at once. So maybe it would inflate to a current max. On the other hand, I had a timer separating it and it still rose permanently for big chunks. This however could also be because the timeouts were too slim or there is an alternate delay since I can at least tell it merges 0-timers to the same tick. The inflation process is very slow to execute and should therefore be avoided (or inited).
 
Status
Not open for further replies.
Top