Failing to measure timer accuracy in linux kernel version 4.4.0-66-generic - timer

I am using hrtimer to set a timer for 10 ms(need accuracy in ns). So while trying to check the timer accuracy I tried using getnstimeofday() and was printing the time and was comparing with the time of next timer call but the time difference between the dmesg time stamp was not matching with difference between the time that I am getting using getnstimeofday() in two successive timer call. Later while exploring found that getnstimeofday() uses CLOCK_REALTIME and function that uses CLOCK_MONOTONIC is better way to measure time difference between two event. So tried both Ktime_get() and Ktime_get_ts() sepeartely but in both cases time difference between two consecutive print was less than 10 ms (~10,000 u sec less for 100 iteration i.e. for 1 sec(10 ms *100)) where as difference between two consecutive dmesg time stamp is more than 10 ms(~200 u sec more for 100 iteration i.e. for 1 sec(10 ms * 100)) for same senario. Can anyone help me what is wrong in my understanding.
Used below functions:
getnstimeofday() --> CLOCK_REALTIME
Ktime_get_ts() --> CLOCK_MONOTONIC
Ktime_get --> CLOCK_MONOTONIC
to calculate the timer accuracy.
Below is just one snippet of kernel logs
< idle>-0 [003] d.h. 6271.497363[= A]: : current time = 6261 sec, current time = 602118348[=C] ns
< idle>-0 [003] d.h. 6272.498933[= B]: : current time = 6262 sec, current time = 602108850[=D] ns
< idle>-0 [003] d.h. 6273.500501: : current time = 6263 sec, current time = 602097738 ns
< idle>-0 [003] d.h. 6274.502080: : current time = 6264 sec, current time = 602098777 ns
< idle>-0 [003] d.h. 6275.503647: : current time = 6265 sec, current time = 602087231 ns
< idle>-0 [003] d.h. 6276.505345: : current time = 6266 sec, current time = 602205944 ns
< idle>-0 [003] d.h. 6277.506775: : current time = 6267 sec, current time = 602057258 ns
< idle>-0 [003] d.h. 6278.508343: : current time = 6268 sec, current time = 602045768 ns
< idle>-0 [003] d.h. 6279.509911: : current time = 6269 sec, current time = 602035489 ns
< idle>-0 [003] d.h. 6280.511597: : current time = 6270 sec, current time = 602143379 ns
A --> dmesg time stamp at T
B --> dmesg time stamp at T+1 sec
C --> time calculated using ktime_get_ts() at time stamp at T
D --> time calculated using ktime_get_ts() at time stamp at T+1 sec
B-A = 1 sec + 157 u sec
D-C = 1 sec - 9498 ns

Related

Converting seconds in date form Numpy Python

The delta_s function calculates the difference of time between 2 dates in the dates with seconds. Then the average median and max values for the differences is calculated. I am trying to convert the times in seconds for average median and max values but it does not work. i want to convert it in the form of x days x hours x minutes x seconds.
Code:
import numpy as np
dates= np.array(['2017-09-15 07:11:00' ,'2017-09-15 11:25:30', '2017-09-15 12:11:10', '2021-04-07 22:43:12', '2021-04-08 00:49:18'],
dtype="datetime64[ns]")
delta_s = np.diff(dates) // 1e9 # nanoseconds to seconds
delta_s = delta_s.astype(np.float64)
delta_avg = np.average(delta_s)
delta_median= np.median(delta_s)
delta_max = np.max(delta_s)
delta_max_index= np.argmax(delta_s)
The line delta_s = np.diff(dates) // 1e9 does not actually convert nanoseconds to seconds. It simply divides 1e9 to the timedelta object but the time unit is preserved timedelta64[ns].
>>> np.diff(dates)
array([ 15270000000000, 2740000000000, 112357922000000000,
7566000000000], dtype='timedelta64[ns]')
>>> np.diff(dates) // 1e9
array([ 15270, 2740, 112357922, 7566],
dtype='timedelta64[ns]')
This may mess up with any calculations you're doing.
Use
delta_s = np.array([np.timedelta64(td, 's') for td in np.diff(dates) ])
Currently there are no inbuilt functions to format timedelta to strings. However you can use something of this sort.
# Function to convert seconds to Human readable Timedelta string
def seconds_to_tdstring(total_seconds):
days, remainder = divmod(total_seconds, 60 * 60 * 24)
hours, remainder = divmod(remainder, 60 * 60)
minutes, seconds = divmod(remainder, 60)
return '{:02} Days {:02} Hours {:02} Minutes {:02} Seconds'.format(int(days), int(hours), int(minutes), int(seconds))
print(seconds_to_tdstring(delta_avg))
Output:
325 Days 04 Hours 24 Minutes 34 Seconds
I have modified the answer from a similar question .

Absence of Consing in SBCL loop

* (defparameter lst (make-list 1000))
LST
* (time (loop for x in lst
for i from 0
unless (= i 500)
collect x))
Evaluation took:
0.000 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
100.00% CPU
47,292 processor cycles
0 bytes consed
How does SBCL build the return list with 0 bytes consed?
Your test case is too small for time. Try (defparameter lst 100000).
Evaluation took:
0.003 seconds of real time
0.003150 seconds of total run time (0.002126 user, 0.001024 system)
100.00% CPU
8,518,420 processor cycles
1,579,472 bytes consed

Get the number of days of the current date with Time

I'm trying to get the number of days untill today. Like:
int days, seconds;
seconds = Time(0); // Get the number of SECONDS from January, 1ยบ 1970 untill now.
days = seconds / (60 * 60 * 24);
printf("%d", days);
The output is: 16326.
But when I use some website that makes the conversion for you, they show 6464 days instead.
What am I doing wrong ?
You are right. There are 30 + 14 = 44 years, which gives about 16000 days.

Microchip PIC period register PR2

From Microchip sample code
PR2 = 2083u; /* Timer2 Period, 19.2 kHz */
How does 2083u correspond to 19.2 kHz, which is
1 / 19.2E03 = 52.083u
They don't correspond at all. Mistake by Microchip?
PR2 = 2083U
makes TIMER2 trigger every 2083 CPU cycles. Calculating
52.083 us / 2083 = 25 ns
1 / 25 ns = 40 MHz
we can conclude that the processor is probably running at FCY = 40 MHz in the example.
The letter u in PR2 = 2038u; does not mean microseconds; it is a C language syntax that makes the integer literal unsigned. See Signedness (Wikipedia).
Setting PR2 to 2083 means that the timer triggers every 2084 (not 2083) clock cycles. When you calculate a timer period, you always have to subtract 1 because the timer value is zero-based.

How set RRD to store for 2 years?

I'm monitoring more than 300 servers, for that I'm using Ganglia.
Which use RRD as database to collect and store data related the resources of each server.
I would like to have a history about 2 years or more, so reading this article, I think that my RRA configuration should be :
RRAs "RRA:AVERAGE:0.5:1:17520"
17520 = (365 days [year] x 2) * 24 [hour]
This is Ganglia default configuration, which is running today:
#
# Round-Robin Archives
# You can specify custom Round-Robin archives here (defaults are listed below)
#
# RRAs "RRA:AVERAGE:0.5:1:244" "RRA:AVERAGE:0.5:24:244" "RRA:AVERAGE:0.5:168:244" "RRA:AVERAGE:0.5:672:244" \
# "RRA:AVERAGE:0.5:5760:374"
#
Is that right my way of thinking or I'm missing something here ?
After studying this subject for a while, I came up with an answer that may help someone in the future. I read these two articles many times, which I recommend.
Read this one first, Creating an initial RRD then read this one. How to create an RRDTool database:
I will try to explain it simply. Format RRA:CF:xff:steps:rows:
RRA: Round Robin Archive
CF: Consolidation Factor
XFF: Xfile Factor
steps
rows
The biggest issue for me was to discover the right value for steps and rows.
After reading, I came up with this explanation:
1 day - 5-minute resolution
1 week - 15-minute resolution
1 month - 1-hour resolution
1 year - 6-hour resolution
RRA:AVERAGE:0.5:1:288 \
RRA:AVERAGE:0.5:3:672 \
RRA:AVERAGE:0.5:12:744 \
RRA:AVERAGE:0.5:72:1480
Keep in mind that our step is 300 seconds, so the idea is very simple:
If I want to resolve one day which has 86400 seconds, as shown in the first example, how many rows do I need? The answer is 288 rows. Why?
`86400 seconds [1 day] / 300 seconds [5 minutes`] = 288 rows
Another example, if I want to resolve:
1 week [ = 604800 seconds ] in 15 minutes [ = 900 seconds ] = 604800/900 = 672 rows
And so it goes on for the other values. This way you are going to find out how many rows you need.
Finding out how many steps you need is very simple, you just have to take the multiplier of your steps.
Let me explain: Our steps are 300 seconds, right?
So if we want to resolve 5 minutes [ = 300 seconds ], we just need to multiply by 1, right?
So, 15 minutes means by 300 seconds x 3, 1 hour means 300 x 12, 6 hours mean 300 x 72 and so on.
In my specific case, I would like to my steps be 30 seconds, so I came up with these structure:
1 every time 30 seconds 1 * 30s = 30s
2 every second time 1 minute 2 * 30s = 1m
4 every third time 2 minutes 4 * 30s = 2m
10 every 10th time 5 minutes 10 * 30s = 5m
20 every 20th time 10 minutes 20 * 30s = 10m
60 every 60th time 30 minutes 60 * 30s = 30m
80 every 80th time 40 minutes 80 * 30s = 40m
100 every 100th time 50 minutes 100 * 30s = 50m
120 every 120th time 1 hour 120 * 30s = 1h
240 every 240th time 2 hours 240 * 30s = 2h
360 every 360th time 3 hours 360 * 30s = 3h
RRA:AVERAGE:0.5:1:120 \
RRA:AVERAGE:0.5:2:120 \
RRA:AVERAGE:0.5:4:120 \
RRA:AVERAGE:0.5:10:288 \
RRA:AVERAGE:0.5:20:1008 \
RRA:AVERAGE:0.5:60:1440 \
RRA:AVERAGE:0.5:80:3240 \
RRA:AVERAGE:0.5:100:5184 \
RRA:AVERAGE:0.5:120:8760 \
RRA:AVERAGE:0.5:240:8760 \
RRA:AVERAGE:0.5:360:8760 \
Which means:
1 hour - 30 seconds resolution
2 hours - 1 minute resolution
4 hours - 2 minutes resolution
1 day - 5 minutes resolution
1 week - 10 minutes resolution
1 month - 30 minutes resolution
3 months - 40 minutes resolution
6 months - 50 minutes resolution
1 year - 1 hour resolution
2 year - 2 hour resolution
3 year - 3 hour resolution
Well, I hope this helps someone, that's all.

Resources