iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0

去年曾經讀過《Effective C++》,當時對 Resource Acquisition Is Initialization (RAII) 的理解較為片面,還停留在「把資源綁定到物件的生命週期」這個層次。例如使用 std::unique_ptr 管理 dynamic memory,離開 scope 時由 destructor 自動釋放資源。這樣可以避免忘記 delete,也能讓 exception 發生時仍然確保資源被正確回收。

這種設計的核心觀念是讓 resource lifetime 與 lexical scope 綁定在一起,因此即使中間發生 early return 也不容易忘記釋放資源。但如果把 C++ 放到低延遲的場景來看,RAII 就不只有「避免 memory leak」這一種功能。因為資源不一定是 memory,也可以是:

  • mutex lock。 e.g. std::lock_guard<std::mutex> lock(mutex);
  • file descriptor。
  • socket。
  • database connection。
  • thread ownership。
  • transaction。
  • temporary buffer。

所以真正值得思考的是:資源的取得與釋放發生在什麼時間點?成本是多少?這個成本是否具有 deterministic 的特性?

假設一個簡易的高頻交易系統有以下 critical path:
┌────────┐
│   Market Data  │
└────────┘
         ↓
┌────────┐
│      Parse     │
└────────┘
         ↓
┌────────┐
|   Risk Check    │
└────────┘
         ↓
┌────────┐
│ Order Decision  │
└────────┘
         ↓
┌────────┐
│   Send Order   │
└────────┘

若這條 path 上出現 auto order = std::make_unique<Order>();,除了物件本身的 construction 之外通常還會涉及 dynamic memory allocation。此時需要關注的就不是 RAII 本身,而是 allocation 是否適合出現在 latency-sensitive 的 critical path。

動態配置通常可以有不錯的平均效能,但其 latency 可能具有較大的 variance,因此很難對 worst-case latency 做出可靠的保證。它可能涉及:

  • allocator 尋找或管理可用的 memory block。
  • allocator metadata 更新。
  • 可能產生 cache miss
  • 在某些 allocator / 使用情境下可能產生 synchronization 或 contention。
  • 在 memory 不足時可能進一步向 OS 取得 memory。
  • 在某些情況下 allocator 可能需要更多 virtual memory,甚至涉及 page mapping、page fault 等更昂貴的操作。

即使在一般的程式架構中多一次 allocation 無傷大雅,但對低延遲系統而言問題會變成:這個 allocation 是否真的需要出現在 critical path? 真正需要避免的是把難以預估的成本放進 latency-sensitive path,盡可能讓會造成 latency spike 的操作發生在可預期的生命週期:

class OrderEngine {
public:
    void initialize() {
        orders_.reserve(10000);
        // Pre-allocate memory for up to 10000 orders to avoid vector reallocation.
    }

    void process() {
        // No vector reallocation as long as capacity is not exceeded.
        orders_.emplace_back();
    }

private:
    std::vector<Order> orders_;
};

RAII 解決的是 resource lifetime 與 ownership 的管理問題,從而達到提升 exception safety 的效果,但其並不會消除 resource acquisition 本身的 runtime cost。而低延遲設計需進一步思考 resource acquisition/release 的時機與成本,避免把 latency variance 較高的資源放進 critical path。


上一篇
[Day 1] 前言 && 大綱
下一篇
[Day 3] Advanced Modern C++ Foundations: STL
系列文
從 C++ 菜鳥到 Low-Latency 勇者:一場分秒必爭的賽局3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言