Lower compute consuming
Use C programming language, or write in assembly. Generally, the answer is: the lower the better, the less the better. I am assuming C programming language below in the answer.
Is it best to use infinite while loop with sleep inside for required time interval of data collection ?
Use OS-specific interface to execute an action periodically. timer_create()
. Calling nanosleep()
in a loop would require to compute time difference to be accurate, which would require getting current time, which is costly. Depending on kernel is better.
In an interrupt handler, only set a single sig_atomic_t
flag in the signal handler. Asynchronically wait in a loop with pause()
for events.
What is the best way to execute all commands in parallel ?
To minimize "compute consuming", do not call fork()
, do not create threads. Use one thread with one big loop with poll()
call waiting for all the events if the events are asynchronous. Such an approach quickly results in spaghetti code - take very special care to properly structure and modularize your code.
open()
all /proc/**
/sys/**
interfaces that you need to monitor, periodically lseek
ing them and reading again, when needing to send data.
So overall, in very pseudocode:
void timer_callback(int) {
flag = 1;
}
int main() {
metrics_read = 0; // keep count of asynchronous reads
timer_create();
foreach(metric) {
int usage = open("/proc/stat", O_NONBLOCK); // for example
}
while(1) {
r = pselect(...);
if (FD_ISSET(socket_to_send_data)) {
// take action, in case like socket was closed or smth
}
if (FD_ISSET(usage)) {
parse(usage_buffer); // parse events as they come
metrics_read++;
}
// FD_ISSET etc. for each metric
if (EINTR && flag) {
flag = 0;
foreach(metric) {
lseek(usage, SEEK_SET, 0)
read(usage, usage_buffer); // non blocking, each read with custom buffer, to let kernel do the job
}
}
if (metrics_read == ALL_METRICS_CNT) {
send_metrics(); // also asynchronous on `socket()` `write()` with O_NONBLOCK
metrics_read = 0;
}
}
Do not write any logs. Logs cause I/O operations, which is "compute consuming". Do not output anything. Also, special work needs to be taken with pselect
to mask signals to "guarantee" that the flag is always properly parsed on time.
is it good way to use & and leave it for background and collect all process ids and verify all are completed ?
Definitely not - fork()
is a very "compute consuming" function, spawning processes is very costly. Best would be not to leave anything "for background" and execute everything in a single threaded single process.
or any other best way is present which for this purpose ?
The lower "compute consuming" would be of course writing a kernel module that does the job. Then, you can specifically manage kernel resources to achieve the lowest possible "compute consuming" while keeping your system linux compatible.