Jump to content
Sign in to follow this  
Heeeere's johnny!

Is it worth using "execVM" instead of "spawn" to save RAM?

Recommended Posts

As the title says.

To explain:

If a mission becomes very big and a lot of functions have to be compiled and loaded into the RAM, I was wondering if there's any sense in using execVM instead of compiling and spawning non-time-critical functions.

Kind regards,

Johnny

Share this post


Link to post
Share on other sites

execVM and spawn do the same thing to my knowledge, fat chance they use the same code to do it too. So the answer to your question would be no, there is no difference in the two.

Share this post


Link to post
Share on other sites
execVM and spawn do the same thing to my knowledge, fat chance they use the same code to do it too. So the answer to your question would be no, there is no difference in the two.

That was not my question. I know they do the same thing.

The question is if it's worth using execVM rather than spawn in large missions in order to save RAM as ArmA's RAM usage is still limited.

Share this post


Link to post
Share on other sites

I don't think it'd be worth it, as I doubt it'd make a difference, they both run code in a scheduled enviroment. Unless you mean saving ram from not having them loaded into memory? In which case I don't think it'd really make that much of a difference. Code doesn't fill a whole lot.

Share this post


Link to post
Share on other sites

What RAM would you be saving? Do a *.sqf on the A3 directory and it comes in at just over 20mb for 2400 odd files, thats including all the BIS_fnc library all the UI scripts all the mission scripts etc.

I think the better question would be time, spawn just creates a thread of something already existing in memory where as execvm has to load and compile/parse the contents of the file but even this is negligible, although execvm in time critical loops as you mention is something you should most likely avoid.

Edited by Larrow

Share this post


Link to post
Share on other sites

[] execVM "myScript.sqf";
//essentially the same as
[] spawn compile preprocessFileLineNumbers "myScript.sqf";

I'd be very surprised if someone were able to run out of RAM. A few nights ago I conducted a test and was able to hold 26905 elements in an array, with each element consisting of a 6 character string. Now, originally I had done the math without string identifiers (because I'm not sure how all that stuff is handled). My finding can be found here. But even with string identifiers, an array of that size only takes up just over 188 kilobytes.

Now considering that my game was running with approximately 1.3GB of the ~4GB available to 32-bit applications, you could create an 14336 of those arrays with the remaining memory, or one large array containing 385,714,285 (yes, that is hundred-millions) before running out of available RAM.

I would be sincerely surprised if RAM was an issue to anyone

---------- Post added at 21:59 ---------- Previous post was at 21:53 ----------

although execvm in time critical loops as you mention is something you should most likely avoid.

Continuing on with what Larrow was saying, because of the time it takes for hard-drive access with preprocessing files, I think it would be much more time-efficient to only execVM one script containing preprocesses for all of your other scripts and saving them into variables, pretty much exactly what the game already does with compiling functions you put in description.ext. Such a file could possible look like:

DE_myScript = compileFinal preprocessFileLineNumbers "myScript.sqf";
DE_myRevive = compileFinal preprocessFileLineNumbers "myRevive.sqf";
DE_myEventHandlers = compileFinal preprocessFileLineNumbers "myEventHandlers.sqf";

Share this post


Link to post
Share on other sites

I don't see any worth in it, if anything a disadvantage. As you know pre-compiled functions are stored in the memory for faster access times where as with execVM it is reading the contents of that file and compiling it over and over again and temporarily storing it in the memory so if anything by using execVM over spawn on a pre-compiled or non-precompiled function would actually be slower given the read times from the file pointer. At best you are utilizing 100KB of memory. Now last time I checked this is 2014 and not 1985 so 100KB (rough max) should be absolutely no problem at all as far as memory usage goes.

What you aim for in coding is performance, not saving small kilobytes of memory when it has no large effect over-all. As said above if using execVM for anything it's for pre-processing stuff (mission initialization) or things that are single-execution only.

Share this post


Link to post
Share on other sites

If it's a function you are using a lot in your mission, it's better to store it in a variable and use spaw.

You'll earn compilation time.

Share this post


Link to post
Share on other sites

OK, I get it. It's not worth it sacraficing time to gain a few Kilobytes of RAM by using execVM.

Nevertheless, as ArmA 3 memory usage does not seem to be clear for some people:

As of the Arma 3 Startup Parameters article, the hard-coded RAM maximum is 2047 MB. You can set that using "-maxMem=2047". For the video memory, it's recommended to NOT use anything beyond 2047 MB. Set that using "-maxVRAM=2047".

I use both commands combined with some batch commands to max out my game performance, but I recommand to NOT use these commands if you run a server at the same time as that will likely crash due to a lack of memory. That's my experience.

Thanks for the discussion and the input, guys.

Have a nice Play!

Johnny

Edited by Heeeere's Johnny!

Share this post


Link to post
Share on other sites

IMHO this is a valid question. I've tried to look for an answer myself too some time ago.

I couldn't get too far with memory consumption of vars/scripts, because I don't know what gets unloaded from mem by the manager to load new vars/scripts. So I would make the question a bit wider: how do these system actually work?

-how is compiled code saved? As text? (it is saved as text in the savegames. So every custon function used is in the saved games, right?)

-what happens, when an execVMed script gets called in a loop, eg. 1000 times. Does it get loaded from HDD & recompiled each time?

What is the advantage of execVM over spawn? Why does this command even exist if we are really talking about hundreds of kilobytes?

Share this post


Link to post
Share on other sites

As non-developers may not look into the C++ source code of BI games, I can only make assumptions.

As far as I understand programming languages, the SQF code will be interpreted by an interpreter or already a compiler which will translate that stuff into either C++ code, Bytecode or Machine code already which will then be loaded into the RAM. (I don't really know anything about that stuff.) Bytecode or machine code is not-human-readable code, so no, compiled SQF code is not saved as strings and to be precise, it's not even "saved" - it's loaded into the RAM where it stays until it's deleted, overwritten or the computer shuts down.

To your execVM question:

Try to create a mission without using execVM a single time. You will realize that in order to achieve that, you'd have to put the whole mission code into the init.sqf (or other Event Scripts). So if you don't want to do that, you'll have to outsource code into other SQF files which you then have to load in using execVM.

Share this post


Link to post
Share on other sites
you'll have to outsource code into other SQF files which you then have to load in using execVM.

You could use #include "myScript.sqf" or spawn compileFinal preprocessFileLineNumbers "myScript.sqf"

Share this post


Link to post
Share on other sites
You could use #include "myScript.sqf" or spawn compileFinal preprocessFileLineNumbers "myScript.sqf"

Granted, I forgot about #include and the function library using an hpp file. But as you know, execVM is simply short for spawn compile preprocessFileLineNumbers. But I'd use 6 letters rather than three words consisting of 37 letters. ^_^

But nitpicky speaking, there's really no need for execVM as you could compile any SQF file using the function library.

Share this post


Link to post
Share on other sites

Zap_MyScript = compile preprocessFileLineNumbers "mysript.sqf";

...

spawn Zap_MyScript / call Zap_MyScript

I thought your mem question was about these type of solutions, which is the setup I exclusively use.

Share this post


Link to post
Share on other sites

Well yeah, my memory question was whether compiling that stuff once and then spawning it or executing it using execVM resp. spawn compile preprocessFileLineNumbers.

Share this post


Link to post
Share on other sites

It's pretty simple, if you use the code once go for the execVM; if you use it multiple times use the spawn

Share this post


Link to post
Share on other sites

There are two simple facts:

1. Scripts ain't big, they don't use much RAM.

2. Reading files from disk is slow.

Giallustio summed it up pretty well.

However, I would really recommend using the function library instead of any compile preprocess constructs.

Share this post


Link to post
Share on other sites

Here is the basic approach as to why one would select spawn, call, execvm

If a script is only going to be used once, then ExecVM

If a script is going to be used more than once, eg a weapon loadout system, AI spawning script etc, then precompile via a cfgfunctions preinit=1 initialisation file (Store in ram for later use before the mission.sqm is even read)

For a precompiled function you then need to decide if it has to be spawned or called

If a precompiled script has a "waituntil" or "sleep" command in or needs to be launched from pre init but not run until post init then spawn that script.

If there are no sleeps or waituntils then call it.

  • Call is linear
  • Spawn is parallel

so in the following scenario this is what will happen for both a called and spawned function

Scenario:

Preinit calls function_1, which calls function_2

  1. PreInit starts
  2. Function_1 is started
  3. Function_2 is started
  4. Function_2 terminates
  5. Function_1 terminates
  6. PreInit terminates

Preinit calls function_1, which spawns function_2

  1. PreInit Starts.............................
  2. Function_1 starts
  3. Function_2 starts
  4. Function_2 could terminate here
  5. Function_1 terminates
  6. Function_2 could terminate here
  7. PreInit terminates
  8. Function_2 could terminate here

Function_2 when spawned is running in a seperate thread to the Preinit and function_1 and is therefore not waiting for anything from them, so it will terminate when it is good and ready dependant on the length of the script, the weight of its commands and the number of delays in it.

recent testing has shown that running too many threads on the server does have a degrading factor on performance, so wherever possible (And its not always possible) keep it linear, the engine will take care of the rest via the 3 millisecond rule

and RAM useage is just a drop in the ocean

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×