You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

裸机环境下自定义实现std::chrono::steady_clock::now()的可行性咨询

Yes, You Can Replace std::chrono::steady_clock::now() With Your Custom Hardware Timer

Absolutely! Since your PowerPC bare-metal environment's default std::chrono::steady_clock is broken (returning -1000000000), hooking your existing monotonic microsecond timer into a custom clock implementation is the perfect solution. Plus, we can make this portable to x64 Linux/Windows with platform-specific fallbacks. Let’s walk through how to do this properly, tailored to GCC 4.9’s C++11 support.

Step 1: Define a Platform-Agnostic Custom Clock

First, create a clock type that adheres to C++11's Clock concept (required for interop with std::chrono utilities). We’ll use preprocessor macros to switch between your PowerPC hardware timer and standard OS clocks for Linux/Windows.

#include <chrono>

// Forward declaration of platform-specific timer function
uint64_t get_monotonic_microseconds();

// Custom steady clock that wraps our timer
struct CustomSteadyClock {
    using rep = uint64_t;
    using period = std::micro; // Our timer returns microseconds
    using duration = std::chrono::duration<rep, period>;
    using time_point = std::chrono::time_point<CustomSteadyClock>;

    static constexpr bool is_steady = true; // Critical for steady_clock behavior

    static time_point now() noexcept {
        return time_point(duration(get_monotonic_microseconds()));
    }
};

// Optional: Alias to match std::chrono naming for easier refactoring
using steady_clock = CustomSteadyClock;

Step 2: Implement Platform-Specific Timer Logic

Now, fill in get_monotonic_microseconds() for each target platform:

PowerPC Bare-Metal (GCC 4.9)

Use your existing hardware timer code here. Make sure to handle any 32-bit timer overflow if needed (e.g., track overflow counts to maintain a 64-bit monotonic counter):

#ifdef __powerpc__
#include "your_hardware_timer_header.h"

static uint64_t overflow_count = 0;
static uint32_t last_timer_value = 0;

uint64_t get_monotonic_microseconds() {
    uint32_t current_timer = read_hardware_timer(); // Your existing function
    if (current_timer < last_timer_value) {
        overflow_count++;
    }
    last_timer_value = current_timer;
    // Assuming your timer counts at 1us per tick (adjust if your timer has a different prescaler)
    return (overflow_count << 32) | current_timer;
}
#endif

x64 Linux

Use clock_gettime() with CLOCK_MONOTONIC for a steady system clock:

#ifdef __linux__
#include <time.h>

uint64_t get_monotonic_microseconds() {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return static_cast<uint64_t>(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;
}
#endif

x64 Windows

Use QueryPerformanceCounter() and QueryPerformanceFrequency() for high-resolution steady time:

#ifdef _WIN32
#include <windows.h>

static LARGE_INTEGER freq;
static bool freq_initialized = false;

uint64_t get_monotonic_microseconds() {
    if (!freq_initialized) {
        QueryPerformanceFrequency(&freq);
        freq_initialized = true;
    }
    LARGE_INTEGER counter;
    QueryPerformanceCounter(&counter);
    return (counter.QuadPart * 1000000) / freq.QuadPart;
}
#endif

Step 3: Use the Clock in Your Code

Now you can use your custom clock just like the standard std::chrono::steady_clock:

#include <iostream>

int main() {
    auto start = steady_clock::now();
    // Your code to time here
    auto end = steady_clock::now();

    auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << "Elapsed time: " << elapsed.count() << "ms\n";

    return 0;
}

Key Considerations for GCC 4.9

  • C++11 Support: GCC 4.9 has full support for C++11 std::chrono, but double-check that you’re compiling with -std=c++11 (or -std=gnu++11 for GNU extensions).
  • Namespace Safety: While we aliased steady_clock to match the standard, avoid directly modifying the std namespace (it’s undefined behavior in standard C++). Using your own alias is safer.
  • Timer Overflow: Ensure your PowerPC timer’s overflow is handled correctly to maintain a strictly monotonic count—this is critical for steady_clock's contract.
  • Microsecond Accuracy: Verify that your hardware timer’s tick rate is indeed 1 microsecond, or adjust the duration period in CustomSteadyClock to match (e.g., std::nano for nanosecond ticks).

Testing the Implementation

  • On PowerPC: Verify that successive calls to now() return strictly increasing values, even when the timer overflows.
  • On Linux/Windows: Compare your clock’s output with the standard std::chrono::steady_clock to ensure consistency.
  • Measure known delays (e.g., a for loop with a fixed number of iterations) to confirm the timing is accurate.

内容的提问来源于stack exchange,提问作者rounin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:34:52