Fichiers
rocm-systems/src/core/core_timer.h
T

64 lignes
1.6 KiB
C++
Brut Vue normale Historique

2020-05-07 03:34:30 -05:00
#ifndef _CORE_TIMER_H_
#define _CORE_TIMER_H_
2023-07-13 19:48:38 +00:00
template <int Size> class CoreTimer {
2020-05-07 03:34:30 -05:00
CoreTimer() {
index_ = 0;
freq_in_100mhz_ = MeasureTSCFreqHz();
}
~CoreTimer() {
if (index_ >= Size) {
printf("ERROR: memory corruption: out of timer data");
abort();
}
}
// retrieve time
double Get() {
double n = 0;
// AMD Linux timing
unsigned int unused;
n = __rdtscp(&unused);
2023-07-13 19:48:38 +00:00
data_[index_] = 10 * n / freq_in_100mhz_; // unit is ns
2020-05-07 03:34:30 -05:00
index_ += 1;
}
2023-07-13 19:48:38 +00:00
double Print()
2020-05-07 03:34:30 -05:00
2023-07-13 19:48:38 +00:00
private :
// timer data
double data_[Size];
2020-05-07 03:34:30 -05:00
// data index
uint32_t index_;
// frequency
double freq_in_100mhz_;
// timing methods
uint64_t CoreTimer::CoarseTimestampUs() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
return uint64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;
}
2023-07-13 19:48:38 +00:00
2020-05-07 03:34:30 -05:00
uint64_t CoreTimer::MeasureTSCFreqHz() {
// Make a coarse interval measurement of TSC ticks for 1 gigacycles.
unsigned int unused;
uint64_t tscTicksEnd;
2023-07-13 19:48:38 +00:00
2020-05-07 03:34:30 -05:00
uint64_t coarseBeginUs = CoarseTimestampUs();
uint64_t tscTicksBegin = __rdtscp(&unused);
do {
tscTicksEnd = __rdtscp(&unused);
} while (tscTicksEnd - tscTicksBegin < 1000000000);
2023-07-13 19:48:38 +00:00
2020-05-07 03:34:30 -05:00
uint64_t coarseEndUs = CoarseTimestampUs();
2023-07-13 19:48:38 +00:00
2020-05-07 03:34:30 -05:00
// Compute the TSC frequency and round to nearest 100MHz.
uint64_t coarseIntervalNs = (coarseEndUs - coarseBeginUs) * 1000;
uint64_t tscIntervalTicks = tscTicksEnd - tscTicksBegin;
return (tscIntervalTicks * 10 + (coarseIntervalNs / 2)) / coarseIntervalNs;
}
};
2023-07-13 19:48:38 +00:00
#endif // _CORE_TIMER_H_