Jump to content
Sparker

A tiny script to measure SQF scheduler load

Recommended Posts

I couldn't find any script/tool/addon which would provide such a basic functionality: how much is ARMA's SQF scheduler loaded right now? Can I run a check every X milliseconds, with the given other scripts running in background?

When we are spawning many different SQF scripts with infinite loops we want to know how much the SQF scheduler is loaded with these scripts. Typically we would try to force the scheduler to execute a simple script and observe the delay between spawning the script and its output. For instance you could spawn a lightning with Zeus and estimate the delay.

 

How it works:

The script I suggest uses the same idea: it runs an infinite loop, where it tries to execute a piece of code as often as the scheduler lets and measuring time intervals between executions. If the scheduler is flooded with many heavy scripts then sequential executions of our tiny script will happen less often. The script also performs exponential averaging of measured intervals.

What it shows:

It shows the delay between executions described above. The delay can help us understand the maximum frequency at which your loops can run(average). It also outputs the overload, measured in percents, which is equal to: overload=100*game FPS*delay=100*game_FPS/SQF_FPS. So if the "overload" is  around100%, SQF scripts are running at roughly the game's frame rate. If it is 200%, then spawned SQF scripts are running at half the game's frame rate, and so on.

Why not just measure performance of single scripts with standard methods?

Maybe you are running other people's scripts in the mission, or you want to get an overview, how much load all the scripts produce.

How to use it:

Run this locally:

Measurements will be output to system chat.

You can fine-tune _a to perform smaller or bigger averaging (smaller _a -> bigger averaging).

[] spawn {
  sl_prev = time;
private _i = 0;
private _ds = 0; // Smoothed value of delta
private _a = 0.009; //
private _N = 30;
while {true} do {
	sleep 0.001;
	private _t = time; // Get current time
	private _delta = _t - sl_prev; // Calculate time passed since previous measurement
	sl_prev = _t; // Store the new time back
	_ds = _a * _delta + (1-_a)*_ds; // Exponential averaging
	
	//Output value every N measurements
	_i = _i + 1;
	if (_i == _N) then {
		_i = 0;
		private _overloadPercent = round(100*diag_fps*_ds);
		systemChat ((format ["Scheduler delay: %1 ms, overload: %2", round(_ds*1000), _overloadPercent]) + "%");
		// Calculate new value for N to produce outputs every 0.5 seconds
		_N = ceil(0.5/_ds);
	};
};

If you want to quickly test the script here's a dummy load you can use. Just run it a few times:

for [{_i=0}, {_i<5}, {_i=_i+1}] do
{
    [] spawn {
		sleep random 1;
		while {true} do {
			sleep 0.5;
			private _a = []; //6 ms @ Core i7 3770
			_a set [70, 0];
			_a = _a apply {2};
			{
				private _sum = 0;
				{
					_sum = _sum + _x;
				}forEach _a;
			} forEach _a;
		};
	};
};

Please share what you think about this!

  • Like 2
  • Thanks 1

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

×