mirror of
https://github.com/google/benchmark.git
synced 2025-03-15 03:30:10 +08:00
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);
|
return MakeTime(kernel_time, user_time);
|
||||||
DiagnoseAndExit("GetProccessTimes() failed");
|
DiagnoseAndExit("GetProccessTimes() failed");
|
||||||
#elif defined(BENCHMARK_OS_QURT)
|
#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>(
|
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;
|
1.0e-6;
|
||||||
#elif defined(BENCHMARK_OS_EMSCRIPTEN)
|
#elif defined(BENCHMARK_OS_EMSCRIPTEN)
|
||||||
// clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) returns 0 on Emscripten.
|
// clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) returns 0 on Emscripten.
|
||||||
@ -160,8 +164,12 @@ double ThreadCPUUsage() {
|
|||||||
&user_time);
|
&user_time);
|
||||||
return MakeTime(kernel_time, user_time);
|
return MakeTime(kernel_time, user_time);
|
||||||
#elif defined(BENCHMARK_OS_QURT)
|
#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>(
|
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;
|
1.0e-6;
|
||||||
#elif defined(BENCHMARK_OS_MACOSX)
|
#elif defined(BENCHMARK_OS_MACOSX)
|
||||||
// FIXME We want to use clock_gettime, but its not available in MacOS 10.11.
|
// 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
|
// Return the CPU usage of the current thread
|
||||||
double ThreadCPUUsage();
|
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)
|
#if defined(HAVE_STEADY_CLOCK)
|
||||||
template <bool HighResIsSteady = std::chrono::high_resolution_clock::is_steady>
|
template <bool HighResIsSteady = std::chrono::high_resolution_clock::is_steady>
|
||||||
struct ChooseSteadyClock {
|
struct ChooseSteadyClock {
|
||||||
@ -25,10 +48,14 @@ template <>
|
|||||||
struct ChooseSteadyClock<false> {
|
struct ChooseSteadyClock<false> {
|
||||||
typedef std::chrono::steady_clock type;
|
typedef std::chrono::steady_clock type;
|
||||||
};
|
};
|
||||||
|
#endif // HAVE_STEADY_CLOCK
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ChooseClockType {
|
struct ChooseClockType {
|
||||||
#if defined(HAVE_STEADY_CLOCK)
|
#if defined(BENCHMARK_OS_QURT)
|
||||||
|
typedef QuRTClock type;
|
||||||
|
#elif defined(HAVE_STEADY_CLOCK)
|
||||||
typedef ChooseSteadyClock<>::type type;
|
typedef ChooseSteadyClock<>::type type;
|
||||||
#else
|
#else
|
||||||
typedef std::chrono::high_resolution_clock type;
|
typedef std::chrono::high_resolution_clock type;
|
||||||
|
Loading…
Reference in New Issue
Block a user