runLoad: run with controlled system load average.

Feb 2008

by Manuel Mollar
mm at nisu.org

Contents

  1. What?
  2. Why?
  3. How?
  4. Usage
  5. Download and install.
  6. Examples
  7. Nisu topics.

What?

This small program allows running resource consumption programs without increment the system load average (Linux).

Why?

When I compute md5 or ed2k of large files, my computer load average (LA) grows dramatically, and interactive work gets difficult. The lost of performance is obviosly due to my slow IDE hard disk, is not a processor problem.
runLoad is a simple program that runs another program without increasing system LA.

How?

runLoad launches the program, but when LA grows, the program is stopped until LA decreases. Obviously, runLoad must never be used in programs that have some time requeriments, like games or CD/DVD recorders. The parameters used by runLoad are:
  • initial LA: if set, process is launched but inmediatelly stopped until system LA is under this value; by default its not set; also, time count begins after initial LA is reached.
  • current LA: the LA meassured by runLoad.
  • LA limit: the current value of LA limit: if current LA > LA limit, the process is stopped; it changes dinamically, to avoid starvation.
  • max LA: upper limit for "LA limit"; over this LA, program is stopped; by default is infinite.
  • min LA: lower limit for "LA limit"; under this LA, the program always run; by default is 0; initial LA has preference.
  • total time: after this elapsed (not processor) time, process is terminated.
  • start time,run_time: the load control only works if start_time < elapsed time < run_time.
When the process is stopped, the value of LA limit grows dinamically to adapt itself to current LA, to avoid starvation. It increases aritmetically, 0.05 every 3 seconds. If requested, it can grow geometrically: 0.01, 0.03, 0.06, 0.10, 0.15, 0.21, etc. When current LA is under LA limit, process is continued, and LA limit is set to current LA+0.10 every 3 seconds, to adapt it to current system circunstance.

Usage

runload [options] [program [arguments]]
Where options are:
  • -v : verbose.
  • -g : sets geometrical increase.
  • -y : calls sync() after stopping the process.
  • -d data_file : uses this path to read loadaverage, see examples,
  • -i ini_LA : sets the initial LA value; if has the form *number, initial LA is set to current LA*number.
  • -n min_LA : sets the min LA value; if has the form *number, min LA is set to current LA*number.
  • -m max_LA : sets the max LA value; if has the form *number, max LA is set to current LA*number.
  • -t minutes, -s minutes, -r minutes: set the total_time, start_time and run_time respectively.
  • -l 1/100 second : sets the sample time, default is 300 (3 seconds).
  • -p process, controls this existing process, instead of creating it.

Download and install.

To install, you can do the following steps:
	wget -O runload.c "http://dwnl.nisu.org/dwnl/runload.c/y"
Then, read the license in runload.c and, if you agree, compile it:
	cc -s -o runload runload.c && rm runload.c
Test it:
	./runload -v -m 0.2 -s 0.2 -r 0.8 -t 1 bash -c "while true; do true; done"
If it works, and you are root, move it elsewhere, for example to /usr/local/bin.

Examples

The previous test:
	runload -v -m 0.2 -s 0.2 -r 0.8 -t 1 bash -c "while true; do true; done"
      
puts your processor at 100% of CPU during 12 seconds, then control starts, controlling the process to have a system LA < 0.2 during 36 seconds, then your processor gets 100% of CPU during 12 more seconds, then bash is terminated.

Trivial examples:

	runload updatedb # runs updatedb maintaining LA controlled
	runload -g -m 3 md5sum * # computes md5 of files, LA newer grows over 3 by this cause
	runload -g -m 5 md4sum -e * # computes ed2k of files, LA newer grows over 5 by this cause
	runload -v -i 1 par2 c parity * # chechks parity of files, do nothing ultil LA < 1
	runload -v -r 2 \
		rsync -aP very_large_file \
			  server:incomplete_very_large_file
	
The las example runs rsync with runload only on this machine, controlling load average only 2 minutes, time while rsync checks large file to find differences. But runload runs only whith the local rsync. To run in both extremes, you can use:
	runload -v -r 2 \
		rsync -aP -e "ssh server" very_large_file \
			  "runload -y -r 4":incomplete_very_large_file
	
If you understand how rsync runs over ssh, you will understand previous example.

To wait for the termination of some proccess:

	runload -l 100 -r 0 -p pid
	
Here an example script that uses it:
	#!/bin/bash
	for p in $(ps axuw | awk '/:[0-9][0-9] '"$*"'/ { print $2}'); do
	  runload -r 0 -p $p
	done
	
It waits for the termination of all the proccess based in his name.

To control temperature instead of loadaverage, supossed that /sys/class/hwmon/hwmon1/device/temp1_input contains the current temp in miligrades, then you run:

	runload -l 50 -d /sys/class/hwmon/hwmon1/device/temp1_input -n 62000 -m 65000 ......
	
to keep program stopped when temp is over 65 and with no control below 62. If -d is specified several times, average is calculated:
	runload -l 50 -d /sys/class/hwmon/hwmon1/device/temp1_input -d /sys/class/hwmon/hwmon1/device/temp2_input -n 62000 -m 65000
	

Bugs?

  • With -p process, if runLoad is terminated by SIGKILL (9) when process is stopped, it will remain stopped. This can be solved using ptrace instead of stopping/continuing process, perhaps in a future version.

  • runLoad takes at least 3 seconds to run, it is the sampling period, so be carefull if you use it in a loop, for example:
    	  for f in somedirs ; do
    	    runload find $f -iname \*txt
    	  done
    	
    will take a lot of time to execute if somedirs is a big list, as every find will take at least 3 seconds.
    To solve it, set the sample time to a lower value, in 1/100 sec, default is 300 (3 sec).

Select Style - Legal