Jump to content
MarkCode82

What goes on under the hood of each scripting command?

Recommended Posts

Why  is why scripting command faster than another, how is this determined?
How many threads is the actual execution engine for ArmA 3?

And how many "jobs" can be active in the schueduler before the system starts to take a performance hit?

Share this post


Link to post
Share on other sites

 

 

Why  is why scripting command faster than another, how is this determined?

 

The scripting command processing speed is determined by the parameters passed and the number of commands the engine has to complete to return a value for the script command. 

 

 

 

How many threads is the actual execution engine for ArmA 3?

 

I dont understand what you mean by this

 

 

 

And how many "jobs" can be active in the schueduler before the system starts to take a performance hit?

 

Theres a performance hit after each thread is spawned, whether it is noticable is another mater.

Share this post


Link to post
Share on other sites

Scripts all run in 1 thread, one after another. 

Scheduler is there so that uncheduled events don't have to wait.

Scripts put in scheduler execute on each simulation, oldest first.

The speed of script command obviously depends on how much work it has to do.

 

For some reading: http://killzonekid.com/arma-scripting-tutorials-sqf-sqs-and-script-scheduler/

And this too: http://foxhound.international/development.html

  • Like 4

Share this post


Link to post
Share on other sites

Scripts all run in 1 thread, one after another. 

Scheduler is there so that uncheduled events don't have to wait.

Scripts put in scheduler execute on each simulation, oldest first.

The speed of script command obviously depends on how much work it has to do.

 

For some reading: http://killzonekid.com/arma-scripting-tutorials-sqf-sqs-and-script-scheduler/

And this too: http://foxhound.international/development.html

So what happens in regards to headless clients is it still running inside 1 thread? I think SQF scripts would probably better described as "procedures" rather than scripts.

execVM , and spawn only return thread handles? Not values, unless explicitly called from within a scheduled script execVM to a call scheduled -> scheduled

 

Furthermore how many procedure based scripts have to be active before the scheduler starts to feel it?

Share this post


Link to post
Share on other sites

So what happens in regards to headless clients is it still running inside 1 thread? I think SQF scripts would probably better described as "procedures" rather than scripts.

execVM , and spawn only return thread handles? Not values, unless explicitly called from within a scheduled script execVM to a call scheduled -> scheduled

 

Furthermore how many procedure based scripts have to be active before the scheduler starts to feel it?

I'm not knowledgeable about HC so someone else will have to answer that. Calling scripts procedures is arguing semantics (there is no OOP in sqf so they are the same thing).

 

ExecVM and spawn do only return thread handles, however saying that they are "not values" is false. Saving thread handles and tracking them can be useful if you know about it. I'm not really sure what exactly you're asking after that

 

"feel it" doesn't mean anything to me, please clarify. As soon as you make a scheduled script, it goes onto the scheduler, so it "feels" it even with just one script. As a test I have had thousands of spawns active, each with a waitUntil {_obj distance player > 200} condition, with no adverse effects to fps or scripts, however, waitUntil is not exactly the most intense command out there and my pc is decent. If you tried having that many threads with an intense command or a crap computer, I wouldn't be surprised if you ran into issues.

Share this post


Link to post
Share on other sites
ExecVM and spawn do only return thread handles, however saying that they are "not values" is false. Saving thread handles and tracking them can be useful if you know about it. I'm not really sure what exactly you're asking after that

I think with that he is trying to say you can't use the values outside of scheduled environment, which isn't true (as far as I'm aware 0_o), you can pass them in as arguments and use them. 

 

I think they won't be able to be used to reference unscheduled environment since it doesn't care about checking thread status much since its a one run and done type deal (why would you bother when it'll be finished in (Probably) under 3 ms anyways).

Share this post


Link to post
Share on other sites

Okay better description and OOP does not resolve to exclusively Procedures, Procedures return nothing in the sense of a function, in mathematics functons have inputs operations and outputs, a spawn'd script yes returns a "script handle value" but no a value with any other type but "script handle" functions can return arrays,booleans,floats,integers, etc.
 

Unless of course you use a [someargs] spawn myTag_fnc_someCode; and have someArgs assigned inside of the script, to a new variable and at the end of the script set that variable to global space and return it in a sense.

 

say:

arg = _this select 0;
_veh = "B_MRAP_01" createVehicle getMarkerPos arg;
SomeGlobalReturn = _veh
// Now veh is in global space and returnable. 

Share this post


Link to post
Share on other sites

Arrays are passed by reference, btw.

Not sure, but this might work:

{ // some scope
    private ["_arr", "_sh", "_ret"];
    _arr = [];

    _sh = _arr spawn {
        // ... some code
        private _return = 2+2;
        _this pushBack _return;
    };

    // ....

    waitUntil {scriptDone _sh};
    _ret = _arr select 0;
    _ret
}

Share this post


Link to post
Share on other sites

 

Arrays are passed by reference, btw.

Not sure, but this might work:

{ // some scope
    private ["_arr", "_sh", "_ret"];
    _arr = [];

    _sh = _arr spawn {
        // ... some code
        private _return = 2+2;
        _this pushBack _return;
    };

    // ....

    waitUntil {scriptDone _sh};
    _ret = _arr select 0;
    _ret
}

 

This ^^^ makes no sense for 2 reasons.

1. To use waitUntil you have to use scheduled script, so why launch another scheduled script from already scheduled script if you can just call it?

2. Returning _ret from scheduled script will return exactly nothing, because scheduled scripts cannot return value.

Share this post


Link to post
Share on other sites

This ^^^ makes no sense for 2 reasons.

1. To use waitUntil you have to use scheduled script, so why launch another scheduled script from already scheduled script if you can just call it?

2. Returning _ret from scheduled script will return exactly nothing, because scheduled scripts cannot return value.

Those are all (bad) decorations to the idea of my post: you can get value from spawned code other than through global variable.

_arr = [];
_sh = _arr spawn {
    _this pushBack (2+2);
};

// ... some time later
// access
_var = _arr select 0; // could become nil

Share this post


Link to post
Share on other sites

This was brought up a long time ago.
I in a lot of my script spawn 1 - 4 threads, those threads then make calls to any subsidiary code

 

This way Threads 1 - 4 work this way. Stack diagram is as follows

[stack 0] [ ] spawn someCode;

[stack 1] [] call someCode2

[stack 2] [] call someCode3

[stack 3] [] call someCode4

[stack 4] [] call someCode5 ([] call to  subCode) (All of stacks from 1 to 4 will remain Within the same spawn'd thread instance.)

etc.

 

 

When you call from within a spawn'd piece of code that code remains within the current scope of the spawn'd script even if you call from and call from a call. They will all remain within the single thread instance of that spawn'd script.

Share this post


Link to post
Share on other sites

They are not threads, they are called scopes. There is no parallel execution for scripts on the same client, all scripts run in sequence. Scheduled scripts can suspend and resume, while unscheduled run from start to finish. Think of scopes as classes for analogy:
 

class main_scope 
{
  class scope1
  {
    class scope1_1
    {

    };
    class scope1_2
    {

    };
  };
  class scope2
  {

  };
};

spawn, execvm will start separate class.

Share this post


Link to post
Share on other sites

There seems to be some disparity in context. You asked how many threads are dedicated by the game (I'm assuming you mean low-level CPU threads) to running scripts, which was answered as 1.

 

That wiki page uses the word "thread", but it's obviously in the context of sqf. From my experience with sqf, the way the functions/scripts are handled in-game is functionally similar to how CPU threading(wikipedia) works (you'd be surprised how much layering is down in a similar manner)

Share this post


Link to post
Share on other sites

https://community.bistudio.com/wiki/Script_%28File%29

? Threads?

 

exec exec starts a thread for a script in SQS syntax.

execVM (Armed Assault only) execVM compiles a script in SQF syntax and starts a thread for it.

spawn (Armed Assault only) spawn starts a thread for compiled Code and returns a script handle.

 

That particular page on BIKI is misleading. It needs total rewrite or deletion.

Share this post


Link to post
Share on other sites

DreadedEntity

spawn requires a script handle when used in the 2D editor. (A3)
In scripts and in the debug console, it is not required, but very useful for keeping track of running scripts. Having a script handle also makes it easy to terminate scripts at any time.

Since spawn creates a new scheduled environment, having an excess of open threads can make the scheduler queue extremely long, significantly increasing the execution time of each thread. (it takes an extremely large amount of threads, though)

 

??? DreadedEntity even calls them threads? They must be a type of thread when it was explained to me arma 3 creates threads, but they're called VM-threads internal to the virtual machine.
But not capable of parallel execution. Not in the sense of ,multi-core utilisation, although it could theoretically by possible to use HC's to distribute processing over multiple cores.

Share this post


Link to post
Share on other sites

DreadedEntity

spawn requires a script handle when used in the 2D editor. (A3)

 

spawn does not "require" a handle. spawn "returns" a handle. In init field in editor it throws error because editor expects init code to return nothing, that's all. 0 = [] spawn {} will make expression return nothing. You can also obtain scheduled script handle from the script itself with _thisScript

Share this post


Link to post
Share on other sites

Any other way to derive/generate a script handle for threads? such as those returned by diag_activeX commands

 

Basically I want a whitelist of threads and any non-whitelisted thread detected in diag_activeX terminated via terminate.

Share this post


Link to post
Share on other sites

Any other way to derive/generate a script handle for threads? such as those returned by diag_activeX commands

 

Basically I want a whitelist of threads and any non-whitelisted thread detected in diag_activeX terminated via terminate.

Pretty sure allowing what would open a door for exploits

Share this post


Link to post
Share on other sites

I have done this before yes. generatedUnique ID's for script handles then passed them to compileFinal as follows


_seedNum = round(random 10000)

_AlphabeticKeys = [A,B,C,D,E,F,G,H,I,J,K]

from 0 to 1 do {

        _randomKeys = [_AlphabeticKeys] call BIS_fnc_selectRandom;

       _convertSeed =  format ["%1",_seedNum];

       _completeKey = _convertSeed + _randomkeys;

       _compileTheCode = compileFinal format ['%1 = execVM "script.sqf" ',_completeKey];

                       };

My solution when I did it used cfgFunctions.hpp and spawn'ing code rather than execVM'ing, as pre-compilation is an excellent optimisation.

Share this post


Link to post
Share on other sites
_seedNum = round(random 10000)

_AlphabeticKeys = [A,B,C,D,E,F,G,H,I,J,K]

from 0 to 1 do {

        _randomKeys = [_AlphabeticKeys] call BIS_fnc_selectRandom;

       _convertSeed =  format ["%1",_seedNum];

       _completeKey = _convertSeed + _randomkeys;

       _compileTheCode = compileFinal format ['%1 = execVM "script.sqf" '];

                       };

 

Needs some tweaking tbh.  Formatting's screwed up on your initial post, but some missing ; and you have a reasonable likelihood of picking the same _completeKey (_seedNum is same for both passes so 1/11 chance of picking same _randomKeys).

 

Also, do something like selectRandom ["A","B","C","D","E","H","I","J","K"] so you don't need to format the variables (which might trip an error anyway), and fix up that loop (for "_whatever" from 0 to 1 do {).

 

edit:  plus " in a string is format error, should be ' or ""

Share this post


Link to post
Share on other sites

I was referring to deriving unknown thread handles.

[] spawn {
     while {true} do {
 
          /* some code */
           sleep 1;
     };
};

how to get a thread handle for that, if its possible?

Share this post


Link to post
Share on other sites

I was referring to deriving unknown thread handles.

[] spawn {
     while {true} do {
 
          /* some code */
           sleep 1;
     };
};

how to get a thread handle for that, if its possible?

If you mean get the thread handle from inside:

Spawn: "In Arma 3, the handle is also available inside the spawned script in _thisScript variable."

  • Like 1

Share this post


Link to post
Share on other sites

Needs some tweaking tbh.  Formatting's screwed up on your initial post, but some missing ; and you have a reasonable likelihood of picking the same _completeKey (_seedNum is same for both passes so 1/11 chance of picking same _randomKeys).

 

Also, do something like selectRandom ["A","B","C","D","E","H","I","J","K"] so you don't need to format the variables (which might trip an error anyway), and fix up that loop (for "_whatever" from 0 to 1 do {).

 

edit:  plus " in a string is format error, should be ' or ""

 

Sorry I was pre-occupied with a new weather engine system simulated in python. I know I did it wrong.

Point is I did it long ago. And the source code might be lost as my PC's HDD could have died. Teaches me for not constantly making backups.

Won't make the same mistake again.

Share this post


Link to post
Share on other sites

If you mean get the thread handle from inside:

Spawn: "In Arma 3, the handle is also available inside the spawned script in _thisScript variable."

 

I mean get the thread handle from outside

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

×