RE: Handling of clock() for RISC-V

"Christian Herber (OSS)" <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <GV1PR04MB951391D6F7192FB681390A6B863D2@GV1PR04MB9513.eurprd04.prod.outlook.com>
Thanks for the reply. If that is the philosophy of newlib, that fine.

Personally, I rarely find myself in an environment where the syscalls for time work (e.g. on spike), and having something that works out of the box is a lot easier than having to override this for every project.
The CLOCKS_PER_SEC is not a big issue. The clock() function can be implemented without using the xcycle(h) registers. Only to make use of time, would you need that. And this can be done simply through a -D definition.
Why do you think the cycle register is not readable in user mode? It is part of the unprivileged specification. The mcycle register is not readbale in user mode, cycle can be read. Check the Zicntr extension. There are even unprivileged pseudo instructions to read cycle (rdcycle[h]).

Christian


From: Kito Cheng <[email protected]>
Sent: Tuesday, 10 December 2024 13:05
To: Christian Herber (OSS) <[email protected]>
Cc: Newlib <[email protected]>
Subject: Re: Handling of clock() for RISC-V

You don't often get email from [email protected]<mailto:[email protected]>. Learn why this is important<https://aka.ms/LearnAboutSenderIdentification>

Hi Christian:



My understanding of newlib in bare-metal applications is that it provides a general implementation, but not necessarily the most optimal one. Users are expected to override these implementations as needed. A clear example of this is libgloss or libnosys in newlib.



For RISC-V, while the cycle register is accessible, it can only be read in machine or supervisor mode. This makes it unsuitable for some scenarios, such as when beginner developers are experimenting with qemu in user mode. Personally, I expect that if a target system has a more appropriate implementation, it would override the default one provided by newlib.



Moreover, using the clock function requires the correct definition of CLOCKS_PER_SEC, which is highly platform-dependent. The current implementation relies on the existence of a time syscall to work properly—even though we all know this approach is somewhat indirect and inefficient.



So ultimately, I think many newlib functions are designed to be generic implementations rather than the best possible ones. For RISC-V, I don’t think we necessarily need to implement clock by directly reading the cycle register. Instead, we should leave it to the BSP or SDK that uses newlib to provide the appropriate override.





---









Christian Herber (OSS) <[email protected]<mailto:[email protected]>> 於 2024年10月30日 週三 21:15 寫道:
Hi all,

I have a question regarding the current implementation libc for RISC-V.
There is no machine specific implementation of clock(). A call to the clock() function will call times() eventually lead to a syscall requesting the time, and converting that back to clock cycles.
I see such a machine specific port has been done for few architectures only (in fact, I only see nvptx). I am sure more architectures have instructions to obtain cycles, why is this not used more?

RISC-V defines a register called cycle (and cycleh for RV32), which provides and easy access to clock cycles.
It is part of the Zicntr extension, which nearly all implementations support, and that should be possible to check through a marco __riscv_zicsr (did not test if the compilers actually do that, but they should).

I cannot imagine many benefits for preferring the syscall (which will likely involve converting cycles to seconds / ns and back) rather than using the register, so I wanted to check if there is something I am missing.

Christian
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.