There are times when you might want to profile your program on parameters like:
- Time taken by program in user mode
- Time taken by program in kernel mode
- Average memory usage by the program
On Linux we have a utility ‘time’ that is designed specifically for this purpose. The utility ‘time’ takes a program name as an input and displays information about the resources used by the program. Also, if the command exists with non-zero status, this utility displays a warning message and exit status.
The syntax of ‘time’ is :
/usr/bin/time [options] program [arguments]
In the above syntax, ‘options’ refer to set of optional flag/values that can be passed to ‘time’ utility to set or unset a particular functionality. The following are the available time command options:
- -v, –verbose : This option is passed when a detailed description of the output is required.
- –quite : This option prevents the ‘time’ utility to report the status of the program.
- -f, –format : This option lets the user to control the format of output of the ‘time’ utility.
- -p, –portability : This option sets the following output format to make the output in conformance with POSIX
real %e user %U sys %S
When the ‘time’ command is run, following is the kind of output it gives :
# /usr/bin/time ls anaconda-ks.cfg bin install.log install.log.syslog mbox 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 3888maxresident)k 0inputs+0outputs (0major+304minor)pagefaults 0swaps
As we can see above, apart from executing the command, the last two lines of the output are the resource information that ‘time’ command outputs.
Note: In the above example, the command ‘time’ was run without any options. So this is a default output generated by the ‘time’ command, which is not formatted properly.
As we can see from the output, the default format of the output generated is :
%Uuser %Ssystem %Eelapsed %PCPU (%Xtext+%Ddata %Mmax)k %Iinputs+%Ooutputs (%Fmajor+%Rminor)pagefaults %Wswaps
The Format Option
This option lets the user to decide the output generated by ‘time’ command. In the last section we discussed the default format that is used in output. Here in this section, we will learn how to specify customized formats.
The format string usually consists of `resource specifiers’ interspersed with plain text. A percent sign (`%’) in the format string causes the following character to be interpreted as a resource specifier.
A backslash (`\’) introduces a `backslash escape’, which is translated into a single printing character upon output. `\t’ outputs a tab character, `\n’ outputs a newline, and `\\’ outputs a backslash. A backslash followed by any other character outputs a question mark (`?’) followed by a backslash, to indicate that an invalid backslash escape was given.
Other text in the format string is copied verbatim to the output. time always prints a newline after printing the resource use information, so normally format strings do not end with a newline character (or `0).
For example :
$ /usr/bin/time -f "\t%U user,\t%S system,\t%x status" date Sun Jan 22 17:46:58 IST 2012 0.00 user, 0.00 system, 0 status
So we see that in the above example, we tried to change the output format by using a different output format.
Since we discussed above that ‘time’ utility displays information about the resource usage by a program, In this section lets list the resources that can be tracked by this utility and the corresponding specifiers.
From the man page :
- C – Name and command line arguments of the command being timed.
- D – Average size of the process’s unshared data area, in Kilobytes.
- E – Elapsed real (wall clock) time used by the process, in [hours:]minutes:seconds.
- F – Number of major, or I/O-requiring, page faults that occurred while the process was running. These are faults where the page has actually migrated out of primary memory.
- I – Number of file system inputs by the process.
- K - Average total (data+stack+text) memory use of the process, in Kilobytes.
- M - Maximum resident set size of the process during its lifetime, in Kilobytes.
- O - Number of file system outputs by the process.
- P - Percentage of the CPU that this job got. This is just user + system times divided by the total running time. It also prints a percentage sign.
- R - Number of minor, or recoverable, page faults. These are pages that are not valid (so they fault) but which have not yet been claimed by other virtual pages. Thus the data in the page is still valid but the system tables must be updated.
- S - Total number of CPU-seconds used by the system on behalf of the process (in kernel mode), in seconds.
- U - Total number of CPU-seconds that the process used directly (in user mode), in seconds.
- W - Number of times the process was swapped out of main memory.
- X - Average amount of shared text in the process, in Kilobytes.
- Z - System’s page size, in bytes. This is a per-system constant, but varies between systems.
- c - Number of times the process was context-switched involuntarily (because the time slice expired).
- e - Elapsed real (wall clock) time used by the process, in seconds.
- k - Number of signals delivered to the process.
- p - Average unshared stack size of the process, in Kilobytes.
- r - Number of socket messages received by the process.
- s - Number of socket messages sent by the process.
- t - Average resident set size of the process, in Kilobytes.
- w - Number of times that the program was context-switched voluntarily, for instance while waiting for an I/O operation to complete.
- x - Exit status of the command.
So we can see that there is a long list of resources whose usage can be tracked by the ‘time’ utility.
Why /usr/bin/time? (Instead of just time)
Lets not use /usr/bin/time and use ‘time’ instead.
$ time -f "\t%U user,\t%S system,\t%x status" date -f: command not found real 0m0.255s user 0m0.230s sys 0m0.030s
As seen from the output above, the ‘time’ command when used without the complete path (/usr/bin/time) spits out an error regarding the ‘-f’ flag. Also the format of output is neither the one specified by us in the command nor the default format we discussed earlier. This lead to a confusion over how this output got generated.
When ‘time’ command is executed without the complete path (/usr/bin/time), then its the built-in ‘time’ command of the bash shell that is executed.
- Use ‘man time’ to view the man page of /usr/bin/time
- Use ‘help time’ to view the information about the bash time built-in.