diff options
| author | Nicolas James <Eele1Ephe7uZahRie@tutanota.com> | 2026-02-21 15:07:18 +1100 |
|---|---|---|
| committer | Nicolas James <Eele1Ephe7uZahRie@tutanota.com> | 2026-02-21 15:07:18 +1100 |
| commit | b7f8df7ba5a08fdf60f2966f0fdcdb06de99c575 (patch) | |
| tree | f366eb9edc126e7d23f3c8acefab01017ab45691 /src | |
| parent | 7f3439714858d4c70f60db71543df15db5708d92 (diff) | |
Improve timestamps accuracy
Diffstat (limited to 'src')
| -rw-r--r-- | src/device_context.cc | 42 | ||||
| -rw-r--r-- | src/device_context.hh | 4 |
2 files changed, 25 insertions, 21 deletions
diff --git a/src/device_context.cc b/src/device_context.cc index 67af3aa..a8e0347 100644 --- a/src/device_context.cc +++ b/src/device_context.cc @@ -52,33 +52,39 @@ void DeviceContext::Clock::calibrate() { std::uint64_t host; }; auto calibrated_result = CalibratedResult{}; - - const auto steady_before = std::chrono::steady_clock::now(); device.vtable.GetCalibratedTimestampsKHR(device.device, 2, std::data(infos), &calibrated_result.device, &this->error_bound); - const auto steady_after = std::chrono::steady_clock::now(); - - this->cpu_time = steady_before + (steady_after - steady_before) / 2; this->device_ticks = calibrated_result.device; this->host_ns = calibrated_result.host; - - // Might need to get physical limits every now and then? - const auto& pd = device.physical_device.properties; - this->ticks_per_ns = pd->limits.timestampPeriod; } DeviceContext::Clock::time_point_t DeviceContext::Clock::ticks_to_time(const std::uint64_t& ticks) const { - auto a = this->device_ticks; - auto b = ticks; - const auto was_before = a > b; - if (was_before) { // it's happened before - std::swap(a, b); - } - - const auto nsec = std::chrono::nanoseconds((b - a) * this->ticks_per_ns); - return this->cpu_time + (was_before ? -nsec : nsec); + const auto& pd = device.physical_device.properties; + const auto ns_tick = static_cast<double>(pd->limits.timestampPeriod); + + const auto diff = [&]() -> auto { + auto a = this->device_ticks; + auto b = ticks; + const auto is_negative = a > b; + if (is_negative) { + std::swap(a, b); + } + const auto abs_diff = b - a; + assert(abs_diff <= std::numeric_limits<std::int64_t>::max()); + const auto signed_abs_diff = static_cast<std::int64_t>(abs_diff); + return is_negative ? -signed_abs_diff : signed_abs_diff; + }(); + + // This will have issues because std::chrono::steady_clock::now(), which + // we use for cpu time, may not be on the same time domain what was returned + // by GetCalibratedTimestamps. It would be more robust to use the posix + // gettime that vulkan guarantees it can be compared to instead. + + const auto diff_nsec = static_cast<std::int64_t>(diff * ns_tick + 0.5); + const auto delta = std::chrono::nanoseconds(this->host_ns + diff_nsec); + return time_point_t{delta}; } } // namespace low_latency
\ No newline at end of file diff --git a/src/device_context.hh b/src/device_context.hh index 9edda61..310b8a7 100644 --- a/src/device_context.hh +++ b/src/device_context.hh @@ -39,11 +39,9 @@ struct DeviceContext final : public Context { const DeviceContext& device; public: - time_point_t cpu_time; + std::uint64_t host_ns; std::uint64_t error_bound; std::uint64_t device_ticks; - std::uint64_t host_ns; - std::uint64_t ticks_per_ns; public: Clock(const DeviceContext& device); |
