read_time_counter port for the RISCV family. (#1378)
This commit is contained in:
parent
f0563475c3
commit
b064eb3994
@ -3,7 +3,13 @@
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
|
||||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64")))]
|
#[cfg(not(any(
|
||||||
|
target_arch = "x86_64",
|
||||||
|
target_arch = "x86",
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "riscv64",
|
||||||
|
target_arsch = "riscv32"
|
||||||
|
)))]
|
||||||
use crate::bolts::current_nanos;
|
use crate::bolts::current_nanos;
|
||||||
|
|
||||||
// TODO: Add more architectures, using C code, see
|
// TODO: Add more architectures, using C code, see
|
||||||
@ -44,13 +50,58 @@ pub fn read_time_counter() -> u64 {
|
|||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read a timestamp for measurements
|
||||||
|
///
|
||||||
|
/// Fetches the full 64 bits of the cycle counter in one instruction.
|
||||||
|
#[cfg(target_arch = "riscv64")]
|
||||||
|
#[must_use]
|
||||||
|
pub fn read_time_counter() -> u64 {
|
||||||
|
let mut v: u64;
|
||||||
|
unsafe {
|
||||||
|
asm!("rdcycle {v}", v = out(reg) v);
|
||||||
|
}
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a timestamp for measurements
|
||||||
|
///
|
||||||
|
/// Fetches the high 32 bits of the cycle counter, its low end
|
||||||
|
/// If the high part has changed, we branch again.
|
||||||
|
/// FIXME: see if the latter is overkill.
|
||||||
|
#[cfg(target_arch = "riscv32")]
|
||||||
|
#[must_use]
|
||||||
|
pub fn read_time_counter() -> u64 {
|
||||||
|
let mut v: u64;
|
||||||
|
let mut hg: u32;
|
||||||
|
let mut lw: u32;
|
||||||
|
let mut cmp: u32;
|
||||||
|
unsafe {
|
||||||
|
asm!("jmp%=:",
|
||||||
|
"rdcycleh {hg}",
|
||||||
|
"rdcycle {lw}",
|
||||||
|
"rdcycleh {cmp}",
|
||||||
|
"bne {hg} {cmp}, jmp%=",
|
||||||
|
hg = out(reg) hg,
|
||||||
|
lw = out(reg) lw,
|
||||||
|
cmp = out(reg) cmp);
|
||||||
|
v = ((hg as u64) << 32) | lw as u64;
|
||||||
|
}
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
/// Read a timestamp for measurements.
|
/// Read a timestamp for measurements.
|
||||||
///
|
///
|
||||||
/// This function is a wrapper around different ways to get a timestamp, fast.
|
/// This function is a wrapper around different ways to get a timestamp, fast.
|
||||||
/// In this way, an experiment only has to
|
/// In this way, an experiment only has to
|
||||||
/// change this implementation rather than every instead of [`read_time_counter`]
|
/// change this implementation rather than every instead of [`read_time_counter`]
|
||||||
/// On unsupported architectures, it's falling back to normal system time, in millis.
|
/// On unsupported architectures, it's falling back to normal system time, in millis.
|
||||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64")))]
|
#[cfg(not(any(
|
||||||
|
target_arch = "x86_64",
|
||||||
|
target_arch = "x86",
|
||||||
|
target_arch = "aarch64",
|
||||||
|
target_arch = "riscv64",
|
||||||
|
target_arch = "riscv32"
|
||||||
|
)))]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn read_time_counter() -> u64 {
|
pub fn read_time_counter() -> u64 {
|
||||||
current_nanos()
|
current_nanos()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user