Tailslayer Dram Hedged Reads

作者 reason-machines2384a003145a無授權條款83 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫3 個月前更新

C++ library for reducing tail latency in RAM reads by hedging across multiple DRAM channels with uncorrelated refresh schedules

AI 產生的概覽

一套 C++ 函式庫,透過在多個 DRAM 通道間對沖讀取,降低刷新停頓造成的尾端延遲。

功能
Tailslayer 是一套 C++ 標頭檔函式庫,將資料複製到刷新週期互不相關的獨立 DRAM 通道上,並同時發出對沖讀取,回傳最先回應的副本。它提供樣板化的 HedgedReader,包含訊號與工作回呼、insert 與 start_workers 方法、核心綁定工具,以及選用的編譯期引數清單。儲存庫另含範例程式、N 路通道對沖基準測試與 DRAM 刷新時序探測工具。
適用情境
適用於建構對延遲敏感的 C++ 系統,尤其是記憶體讀取中 DRAM 刷新最壞情況停頓成為問題時,例如事件驅動或低延遲工作負載。適合能將執行緒綁定至核心,並在 AMD、Intel 或 AWS Graviton 硬體上調整 DRAM 通道選擇位元的開發者。
執行需求
需要 C++17 或更新版本的編譯器,並將 tailslayer 標頭檔加入包含路徑;儲存庫從 GitHub 複製並以 make 建置。基準測試與刷新探測需要 sudo 與即時排程(chrt),通道調校則取決於平台特定的 DRAM 通道位元。此技能本身不附帶指令碼,僅為說明文件。

Tailslayer — DRAM Hedged Read Library

Skill by ara.so — Daily 2026 Skills collection.

Tailslayer is a C++ library that reduces tail latency in RAM reads caused by DRAM refresh stalls. It replicates data across multiple independent DRAM channels with uncorrelated refresh schedules, issues hedged reads across all replicas simultaneously, and returns whichever result responds first — eliminating worst-case stall spikes from DRAM refresh cycles.

Works on AMD, Intel, and AWS Graviton using undocumented channel scrambling offsets.


How It Works

  • Data is replicated N times, each copy placed on a different DRAM channel
  • Each replica is monitored by a worker pinned to a separate CPU core
  • When a read is triggered (via your signal function), all replicas are read simultaneously
  • Whichever channel responds first wins; the result is passed to your work function
  • DRAM refresh on one channel cannot stall all channels simultaneously → tail latency is eliminated

Installation

Copy the header into your project

bash
git clone https://github.com/LaurieWired/tailslayer.gitcp -r tailslayer/include/tailslayer /your/project/include/

Include in your code

cpp
#include <tailslayer/hedged_reader.hpp>

Build the provided example

bash
git clone https://github.com/LaurieWired/tailslayer.gitcd tailslayermake./tailslayer_example

Key API

tailslayer::HedgedReader<T, SignalFn, WorkFn, SignalArgs, WorkArgs>

Template parameters:

ParameterDescription
TValue type stored and read
SignalFnFunction that waits for a trigger and returns the index to read
WorkFnFunction called with the value immediately after read
SignalArgs(optional) tailslayer::ArgList<...> of compile-time args to signal function
WorkArgs(optional) tailslayer::ArgList<...> of compile-time args to work function

Constructor optional parameters

cpp
HedgedReader(    uint64_t channel_offset = DEFAULT_OFFSET,  // undocumented channel scrambling offset    uint64_t channel_bit    = DEFAULT_BIT,     // bit used for channel selection    std::size_t n_replicas  = 2                // number of DRAM channel replicas)

Methods

cpp
reader.insert(T value);       // Insert value, replicated across all channelsreader.start_workers();       // Launch per-channel worker threads (blocking)

Utilities

cpp
tailslayer::pin_to_core(core_id);        // Pin calling thread to a specific coretailslayer::CORE_MAIN                    // Constant: recommended core for main thread

Minimal Usage Pattern

cpp
#include <tailslayer/hedged_reader.hpp>#include <cstdint>#include <cstdio>
// 1. Define your signal function — waits for your event, returns index to read[[gnu::always_inline]] inline std::size_t my_signal() {    // Example: busy-wait for an external flag, then return the index    extern volatile std::size_t g_index;    extern volatile bool g_trigger;    while (!g_trigger) {}    g_trigger = false;    return g_index;}
// 2. Define your work function — receives the read value immediatelytemplate <typename T>[[gnu::always_inline]] inline void my_work(T val) {    // Process val as fast as possible    printf("Read value: %u\n", (unsigned)val);}
int main() {    using T = uint8_t;
    // Pin main thread to recommended core    tailslayer::pin_to_core(tailslayer::CORE_MAIN);
    // Construct reader with 2 replicas (default)    tailslayer::HedgedReader<T, my_signal, my_work<T>> reader{};
    // Insert data — replicated across both DRAM channels automatically    reader.insert(0x43);    reader.insert(0x44);
    // Launch workers — blocks; workers spin until signal fires    reader.start_workers();
    return 0;}

Passing Arguments to Signal and Work Functions

Use tailslayer::ArgList<...> to pass compile-time integer arguments:

cpp
#include <tailslayer/hedged_reader.hpp>
// Signal function with args[[gnu::always_inline]] inline std::size_t my_signal(int threshold, int channel) {    // use threshold and channel...    return 0;}
// Work function with argstemplate <typename T>[[gnu::always_inline]] inline void my_work(T val, int multiplier) {    volatile int result = (int)val * multiplier;    (void)result;}
int main() {    using T = uint8_t;    tailslayer::pin_to_core(tailslayer::CORE_MAIN);
    tailslayer::HedgedReader<        T,        my_signal,        my_work<T>,        tailslayer::ArgList<10, 1>,   // args forwarded to my_signal: threshold=10, channel=1        tailslayer::ArgList<2>        // args forwarded to my_work:   multiplier=2    > reader{};
    reader.insert(0xAB);    reader.start_workers();}

Custom Channel Configuration

Override channel offset, channel bit, and replica count in the constructor:

cpp
// Example: 4 replicas, custom channel bit 8 (common for AMD/Intel)tailslayer::HedgedReader<T, my_signal, my_work<T>> reader{    /* channel_offset */ 0,    /* channel_bit    */ 8,    /* n_replicas     */ 4};

Note: N-way (more than 2 replicas) hedging requires using the benchmark code in discovery/benchmark/. The main library header currently exposes 2 channels by default.


Running Benchmarks

Channel-hedged read benchmark (N-way)

bash
cd discovery/benchmarkmakesudo chrt -f 99 ./hedged_read_cpp --all --channel-bit 8

Flags:

FlagDescription
--allRun all channel configurations
--channel-bit NSpecify the DRAM channel selection bit (try 6, 7, or 8 for your platform)

DRAM refresh spike timing probe

bash
cd discoverygcc -O2 -o trefi_probe trefi_probe.csudo ./trefi_probe

This measures your DRAM's tREFI refresh interval and the worst-case stall duration — useful for calibrating expectations.


Platform Notes

PlatformTypical Channel BitNotes
AMD (Zen)6 or 7Verify with benchmark
Intel6, 7, or 8Run benchmark with --all
AWS Graviton8Confirmed working

Use --all in the benchmark to auto-detect the best channel bit for your system.


Common Patterns

Low-latency trading / event-driven read

cpp
// Pre-load order book prices into hedged reader// Signal on market data arrival, process immediately
[[gnu::always_inline]] inline std::size_t await_market_signal() {    extern volatile std::size_t g_book_idx;    extern volatile bool g_tick;    while (!g_tick) { __builtin_ia32_pause(); }    g_tick = false;    return g_book_idx;}
template <typename T>[[gnu::always_inline]] inline void process_price(T price) {    // Submit order using price with minimal latency    extern void submit_order(T);    submit_order(price);}
int main() {    tailslayer::pin_to_core(tailslayer::CORE_MAIN);    tailslayer::HedgedReader<uint64_t, await_market_signal, process_price<uint64_t>> reader{};    for (uint64_t price : preloaded_prices) {        reader.insert(price);    }    reader.start_workers();}

Preloading a lookup table across channels

cpp
// Each insert automatically maps to correct DRAM channel via address calculation// Access is via logical index — tailslayer manages physical placement
tailslayer::HedgedReader<uint32_t, my_signal, my_work<uint32_t>> reader{};
std::vector<uint32_t> lut = {100, 200, 300, 400};for (auto v : lut) {    reader.insert(v);}reader.start_workers();

Troubleshooting

High latency still observed

  • Verify you are using the correct --channel-bit for your CPU. Run benchmark with --all.
  • Ensure workers are pinned to isolated cores (use isolcpus= kernel boot parameter).
  • Run with real-time scheduling: sudo chrt -f 99 ./your_binary

Build errors — missing headers

  • Confirm include/tailslayer/hedged_reader.hpp is on your include path.
  • Requires C++17 or later: add -std=c++17 to your compiler flags.

Workers don't start / deadlock

  • start_workers() is blocking. It launches threads and waits — your signal function must eventually return.
  • Ensure the signal function does not block indefinitely during testing.

Data corruption / wrong values

  • Each insert() replicates the value N times (one per channel). Logical indexing is handled internally — do not attempt to address replicas directly.
  • Do not modify inserted data after insert() is called.

Platform not supported

  • Tailslayer uses undocumented DRAM channel scrambling offsets. If your platform is not AMD, Intel, or Graviton, run the trefi_probe and benchmark tools to characterize refresh behavior before using the library in production.

Project Structure

tailslayer/├── include/tailslayer/│   └── hedged_reader.hpp       # Main library header (copy this)├── tailslayer_example.cpp      # Usage example├── discovery/│   ├── trefi_probe.c           # DRAM refresh spike timing tool│   └── benchmark/              # N-way channel hedging benchmark└── Makefile

來源與署名

來源:reason-machines/trending-skills位於skills/tailslayer-dram-hedged-reads提交2384a00

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架