Anyway, i wonder what tools exist to test the speed/execution time, cpu cycles and ram usage of a c program in FreeBSD.
At first: congratulations. You are getting deeper, and having fun with it. Very good! Keep on that good work!
Exact measurement of speed/execution time is kind of a bit tricky.
You can use the
time.h in C:
C:
#include <stdio.h>
#include <time.h>
int main()
{
int t_start, t_end;
/* other code */
t_start = clock();
/*
....code to be measured ....
*/
t_end = clock();
printf("%d\n", t_end - t_start);
/* other code */
return 0;
}
You can use
getrusage(2) to get RAM usage. But also the debugger can help.
For to get exact execution times - 'how many clock cycles does this part of code needs to be executed on the CPU?' it's needed to be known how many clock cycles each machine command takes, knowing the machine code of a certain part of code (
objdump(1), e.g.
objdump -d a.out) which delivers the number of clock cycles needed for that part, those computed with the CPU's clock frequency gives the time. The debugger can help you on that.
But the point is: As long as it's just out of pure curiosity, you may get lost into details which are not important to know as long as you don't really need to meet real time requirements or need exact timing, e.g. control some fast technical process.
The actual question is: What means exact execution time on a modern personal computer, where you not only have to deal with an OS (see coming text), but also 2 to 64 core CPUs running at 1.5 to 5GHz? And how useful is this to know, or better when is it worth the effort to get this value?
You see:
Just measuring how long a program part, or even the whole prog runs on your system is not always very meaningful.
When you place some code between both t_...=clock(); that uses to run a couple of seconds, and then run the same object code a couple of times, you will not receive the same timespan every time.
Explanation:
You are using a
time sharing OS. So you're not running your prog directly on the CPU ("bare metal"), but let the OS handle this job. Doesn't matter if you're using BSD, Linux, MacOS, Windows or whetever - the principal on a time sharing OS is always the same.
Running a prog on an ts OS works this way: You tell the OS, 'Hey! Run this!' Then the OS (there is also communication between the shell and the kernel, and also the shell then has jobs to do, e.g. when you use printf; not going into details here) needs to see, when to fit it into its schedule, where to slip it between all the other jobs it currently does. Of course, under normal cicumstances (you are not currently building world parallel, which made your machine being already pretty near 100% load) there is way more capacity left to just execute a small piece of software you ask for en passant. And since you are the user, you get a higher priority for the jobs you ask for than the OS's jobs running in background when there is nothing else to do. But anyway it needs some CPU time to run, needs to slip in somewhere, needs to be loaded, and then executed, when there is time for it.
As the user infront of a machine you don't recognize anything of that. At least you shall not. (Except of course the program takes a while to run, e.g. counts a million times from zero to ten thousand, but that's not the point here) If so then those are the so called 'lags'. Commonly known as a cause of losing a player's life on a virtual battlefield, because the internet connection had a lag, and your game froze for a few tenth seconds. But it's also, when you realize your mousepointer is not running smoothly, there is a significant delay between pressing a key and seeing the letter appear, or something like that. It's when your machine's load is over 100% its capacity, and the OS gets problems to schedule enough CPU time for all the tasks asked to be done.
A modern time sharing OS has a bunch of jobs to do. Even organizing all the jobs is a job of its own. The point is, at least the jobs according directly with the user's interaction (UI) are all (shall be) done so damnd fokkin' quickly, that for a human it seems they are happening instantaneously at the same time, or at least fast enough not to be recognize there are any delays. Or delays happen very seldom and are very short so not disturbing.
While other jobs not having a direct connection to the user's interactions with the machine, the time when they are started and the timespan they need to be done are of lower priority. It doesn't matter really how long those take to be finished, as long as they are done. For example it doesn't matter if the new version of the source code file you're writing is saved to disk within 31 ms or 329 ms - anyway fast enough for the job. Of course we are talking computer's time scales. Which means a couple of seconds are "just sometime in the future, doesn't matter when."
Anyway, and that's the core point, there are delays, constantly many, many delays. Most of the times they are too short for a human to be recognized, so his work at the machine feels smooth.
<[begin side track]>
There is a neuropsychological limit of perception - a minimum time that nerves respond to a stimulus. Since there is not only a very large difference between seeing, hearing,...feeling a touch with your fingertips or with your toes, but also between individual humans, to give a general number for it is not actually correct. But to give a rough idea which for many practical applications is not complete bogus, one could say anything shorter than app. 30 ms is recognized by a human as immediately, instantaneously, not even recognized there was a delay at all.
For a modern CPU 30 ms is a small eternity - you can do a lot many things in that time.
<[end side track]>
When you let a program run on an OS, supposing a very small C program doing just some short calculations with pregiven values (named "c" here), and there is no waiting for user interaction, the time line would look something like this:
[.................................- wait for the OS to begin execution -........................................][c][...............................- wait for and then printf("", result); - ..................................]
All this waiting happens in milliseconds. So an execution of a very small program seems to happen at the very moment you hit the enter key to start it, while in fact most of the time is not needed for the program's execution, but for the shell and OS to handle its "organization."
Point is, all that scheduling by the OS, wait to fit in, wait for to run it in most of the times is by far way more than short enough, so the user is not disturbed in his workflow on an "office machine" ("personal computer"). But there are those times. And above all they not always have the exact same length. So their timespan is not predictable. And, like in this example, they can exceed the actual execution time of a small prog by several times (even if not recognized.)
Plus, modern CPUs do such things like code prediction, and running pieces of code parallel.
So, again:
As long as you don't really need to deal with exact timing, e.g. having to control some fast technical process, or need to speed up your software, because it runs to slow to meet some real time requirements (producing lags), then just do what the majority does: Don't bother much, and simply rely on the machine will run it fast enough.

Besides, you can gain way much more speed by chosing the right algorithm, or tighten your code, than finetuning at clock cycles.
"Premature optimization is the root of all evil."
[Donald Knuth]