mirror of https://github.com/google/benchmark.git
Improve compatibility with Hexagon hardware (#1785)
The customization done via BENCHMARK_OS_QURT works just fine with the Hexagon simulator, but on at least some Hexagon hardware, both `qurt_timer_get_ticks()` and `std::chrono::now()` are broken and always return 0. This fixes the former by using the better-supported (and essentially identical `qurt_sysclock_get_hw_ticks()` call, and the latter by reading a 19.2MHz hardware counter (per suggestion from Qualcomm). Local testing seems to indicate these changes are just as robust under the simulator as before.
This commit is contained in:
parent
a4cf155615
commit
7f992a553d
|
@ -126,8 +126,12 @@ double ProcessCPUUsage() {
|
|||
return MakeTime(kernel_time, user_time);
|
||||
DiagnoseAndExit("GetProccessTimes() failed");
|
||||
#elif defined(BENCHMARK_OS_QURT)
|
||||
// Note that qurt_timer_get_ticks() is no longer documented as of SDK 5.3.0,
|
||||
// and doesn't appear to work on at least some devices (eg Samsung S22),
|
||||
// so let's use the actually-documented and apparently-equivalent
|
||||
// qurt_sysclock_get_hw_ticks() call instead.
|
||||
return static_cast<double>(
|
||||
qurt_timer_timetick_to_us(qurt_timer_get_ticks())) *
|
||||
qurt_timer_timetick_to_us(qurt_sysclock_get_hw_ticks())) *
|
||||
1.0e-6;
|
||||
#elif defined(BENCHMARK_OS_EMSCRIPTEN)
|
||||
// clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) returns 0 on Emscripten.
|
||||
|
@ -160,8 +164,12 @@ double ThreadCPUUsage() {
|
|||
&user_time);
|
||||
return MakeTime(kernel_time, user_time);
|
||||
#elif defined(BENCHMARK_OS_QURT)
|
||||
// Note that qurt_timer_get_ticks() is no longer documented as of SDK 5.3.0,
|
||||
// and doesn't appear to work on at least some devices (eg Samsung S22),
|
||||
// so let's use the actually-documented and apparently-equivalent
|
||||
// qurt_sysclock_get_hw_ticks() call instead.
|
||||
return static_cast<double>(
|
||||
qurt_timer_timetick_to_us(qurt_timer_get_ticks())) *
|
||||
qurt_timer_timetick_to_us(qurt_sysclock_get_hw_ticks())) *
|
||||
1.0e-6;
|
||||
#elif defined(BENCHMARK_OS_MACOSX)
|
||||
// FIXME We want to use clock_gettime, but its not available in MacOS 10.11.
|
||||
|
|
29
src/timers.h
29
src/timers.h
|
@ -15,6 +15,29 @@ double ChildrenCPUUsage();
|
|||
// Return the CPU usage of the current thread
|
||||
double ThreadCPUUsage();
|
||||
|
||||
#if defined(BENCHMARK_OS_QURT)
|
||||
|
||||
// std::chrono::now() can return 0 on some Hexagon devices;
|
||||
// this reads the value of a 56-bit, 19.2MHz hardware counter
|
||||
// and converts it to seconds. Unlike std::chrono, this doesn't
|
||||
// return an absolute time, but since ChronoClockNow() is only used
|
||||
// to compute elapsed time, this shouldn't matter.
|
||||
struct QuRTClock {
|
||||
typedef uint64_t rep;
|
||||
typedef std::ratio<1, 19200000> period;
|
||||
typedef std::chrono::duration<rep, period> duration;
|
||||
typedef std::chrono::time_point<QuRTClock> time_point;
|
||||
static const bool is_steady = false;
|
||||
|
||||
static time_point now() {
|
||||
unsigned long long count;
|
||||
asm volatile(" %0 = c31:30 " : "=r"(count));
|
||||
return time_point(static_cast<duration>(count));
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#if defined(HAVE_STEADY_CLOCK)
|
||||
template <bool HighResIsSteady = std::chrono::high_resolution_clock::is_steady>
|
||||
struct ChooseSteadyClock {
|
||||
|
@ -25,10 +48,14 @@ template <>
|
|||
struct ChooseSteadyClock<false> {
|
||||
typedef std::chrono::steady_clock type;
|
||||
};
|
||||
#endif // HAVE_STEADY_CLOCK
|
||||
|
||||
#endif
|
||||
|
||||
struct ChooseClockType {
|
||||
#if defined(HAVE_STEADY_CLOCK)
|
||||
#if defined(BENCHMARK_OS_QURT)
|
||||
typedef QuRTClock type;
|
||||
#elif defined(HAVE_STEADY_CLOCK)
|
||||
typedef ChooseSteadyClock<>::type type;
|
||||
#else
|
||||
typedef std::chrono::high_resolution_clock type;
|
||||
|
|
Loading…
Reference in New Issue