TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
backoff.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// Back-off for a GPU that refused work (design doc 07 ยง4).
4//
5// With the shared GPUs full of other jobs, every cost-to-go field asked the driver for free memory and the threads queued
6// on its lock for seconds before falling back to the CPU: interf_u took 2,900 s instead of 20 s, with byte-identical output
7// (soak 2026-10-25, phase 6b). A device that refused is therefore not asked again for a while, the delay doubling while it
8// stays full (30 s, 1, 2, 4, 8 min, then 15 min); the CPU reference meanwhile computes the same results. Wall time decides
9// only which of two identical paths runs, so outputs cannot change (rule 2).
10#include <algorithm>
11#include <atomic>
12#include <cstdint>
13
14namespace tmk::gpu {
15
17 public:
18 static constexpr std::int64_t kFirstMs = 30'000, kMaxMs = 900'000;
19
20 // True while a refusal is recent enough that the device should not be asked.
21 bool waiting(std::int64_t now_ms) const { return now_ms < until_ms_.load(std::memory_order_relaxed); }
22
23 // The device refused (not enough free memory, or allocation failed): wait, twice as long as last time.
24 void refused(std::int64_t now_ms) {
25 const int n = refusals_.fetch_add(1, std::memory_order_relaxed);
26 const std::int64_t delay = std::min(kFirstMs << std::min(n, 5), kMaxMs);
27 until_ms_.store(now_ms + delay, std::memory_order_relaxed);
28 }
29
30 // The device took work again: the next refusal starts from the first delay.
31 void accepted() { refusals_.store(0, std::memory_order_relaxed); }
32
33 // Delay a refusal at this point would set (for tests and logs).
34 std::int64_t next_delay_ms() const { return std::min(kFirstMs << std::min(refusals_.load(std::memory_order_relaxed), 5), kMaxMs); }
35
36 private:
37 std::atomic<std::int64_t> until_ms_{0};
38 std::atomic<int> refusals_{0};
39};
40
41} // namespace tmk::gpu
static constexpr std::int64_t kMaxMs
Definition backoff.hpp:18
void refused(std::int64_t now_ms)
The device refused (not enough free memory, or allocation failed): wait, twice as long as last time.
Definition backoff.hpp:24
bool waiting(std::int64_t now_ms) const
True while a refusal is recent enough that the device should not be asked.
Definition backoff.hpp:21
std::int64_t next_delay_ms() const
Delay a refusal at this point would set (for tests and logs).
Definition backoff.hpp:34
static constexpr std::int64_t kFirstMs
Definition backoff.hpp:18
void accepted()
The device took work again: the next refusal starts from the first delay.
Definition backoff.hpp:31