clock_gettime function doesn't scale to real time.. and changing CNTFRQ_EL0 doesn't make any change..(arm64)

Linus Probert linus.probert at gmail.com
Fri Nov 4 08:04:43 EDT 2022


On Fri, Nov 04, 2022 at 06:04:15PM +0900, Chan Kim wrote:
> Hello linux experts and newbies,
> 
> I have ported linux on our arm64 fpga board. Both 5.10.0 and 5.15.xx works
> ok with minimal config.
> I have run a simple application and timed the processing time using
> clock_gettime function.
> It felt like it took almost 2.3 seconds but the program say it took only
> 0.36 seconds.
> Here is how I did  it in the application.

Hello, while I'm by no means an authority on kernel code and the board you
are developing for I did spot some problems with your provided example
code.

> 
> 	Int main() {
> 
> 	struct timespec start, stop;
> 	    float exec_time_sec, exec_time_nsec;
> 	
> 	//check start time
> 	    if (clock_gettime(CLOCK_REALTIME, &start) == -1 )  {
> 	        perror ("clock_gettime");
> 	        exit(EXIT_FAILURE);
> 	    }

CLOCK_REALTIME is defined as "wall time" in `man clock_gettime` so it
should not be impacted by the CPU frequency.

> 
> 	Do something... (calculate fibonacci value for 1 ~ 30)
> 
> 	//check end time
> 
> 	    if (clock_gettime(CLOCK_REALTIME, &stop) == -1 )  {
> 	        perror ("clock_gettime");
> 	        exit(EXIT_FAILURE);
> 	    }
> 
> 	    //Normalize to mili second
> 	    exec_time_sec = (float)(stop.tv_sec - start.tv_sec);

You are not converting seconds to milliseconds here but in the printf
call below you are asuming it's the same time unit.

> 	    exec_time_nsec = (float)((double)(stop.tv_nsec -
> start.tv_nsec)/(double)BILLION);

1 millisecond is 0.000001 nanoseconds. So you want MILLION here. Also,
it's a lot of casting.

> 
> 	    printf("Execution time : %f sec\n", exec_time_sec +
> exec_time_nsec);
> 	
> 	return 0;
> 	}
> 
> 
> I used u-boot program for loading linux kernel and the u-boot program sets
> the CNTFRQ_EL0 register with 5000000. 
> (which is 5MHz, I heard the system clock runs at 5MHz in the board).
> The description of the register in armv8 arch manual says :
> 
> This register is provided so that software can discover the frequency of the
> system counter. It must
> be programmed with this value as part of system initialization. The value of
> the register is not
> interpreted by hardware.
> 
> I tried setting the CNTFRQ_EL0 with 20Mhz, expecting the execution to be
> displayed 4 times shorter but it is the same!
> I couldn't find how linux uses clock_gettime.
> How can I solve this problem?
> Any advice will be deeply appreciated.
> 
> Thank you!
> 
> Chan Kim
> 
> 
> 
> 

I would suggest that you have a read through `man clock_gettime`. After
fixing your code. In particular you might be interested in the actual
CPU time clocks. That said. I'm not sure these are the system calls you
should be looking at.

Br,
Linus Probert

> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies




More information about the Kernelnewbies mailing list