Upgrade to Pro — share decks privately, control downloads, hide ads and more …

get updated to the latest realtime audio processings knowledge base (2023) (再履修: 2023年までの リアルタイムオーディオ処理)

Atsushi Eno
February 28, 2023

get updated to the latest realtime audio processings knowledge base (2023) (再履修: 2023年までの リアルタイムオーディオ処理)

Atsushi Eno

February 28, 2023
Tweet

More Decks by Atsushi Eno

Other Decks in Technology

Transcript

  1. 参考資料(テキスト、動画) Real-Time audio processing 101: time waits for nothing (Ross

    Bencina) 🔗 ADC19 - Real-Time 101 Pt. I / Pt. II ADC21 - C++ Standard Library for Real-time Audio 🔗 "Allocators: the Good Parts" 🔗 "practical memory pool based allocators for modern C++" ADC22 - Thread synchronisation in real-time audio processing with RCU (Read-Copy-Update) The Ardour DAW – Latency Compensation and Anywhere-to-Anywhere Signal Routing Systems ...
  2. 動的メモリ確保はもはや禁忌ではない? std::pmr (polymorphic memory resource) でリアルタイム動的メモリ確保 - libc++で未実装 / cradleapps/realtime_memory

    (プライベート実装) - 事前アロケーション、 single threaded, O(1) - std::pmr::monotonic_buffer_resource, std::pmr::unsynchronised_pool_resrouce, std::pmr_polymorphic_allocator - copy constructorやmoveなどでallocatorはコピーされない(!) - std::mapではなくstd::pmr::mapが用意されている ※tcmalloc、rpmalocなどモダンな汎用アロケーターもnon RT-safe ※原理原則は変わっていない  (これらはシステムレベルの確保/解放を行わない)
  3. オーディオスレッドと排他制御 全部説明はできないので簡潔に - データ共有はない? → FIFO - RTスレッドはない? → std::mutex

    - 小さいデータ? → std::atomic - リソース確保失敗してもよい? → try_lock - RTスレッドがデータを更新しない? → CAS - non-RTスレッドがデータを更新しない? → ダブルバッファリング - どっちも更新しうる → CAS + FIFO でがんばる… ※CAS: (atomic) compare and set (or swap)
  4. オーディオスレッドと排他制御 補足: 「小さいデータ」判定: std::atomic<T>::is_always_lock_free volatileはメモリモデルの規定がないので std::atomicを使うべき 「リソース確保の失敗してもよい」場合 - ウェーブテーブルの更新など(空白で再生) std::try_to_lockはOKだがstd::mutexはリリース時にブロックの可能性があるので

    NG (多分そんな実装は多くないけど標準としては wait-freeではない) std::mutexの代わりにstd::atomic_flagを使った単純なspin lockを使えばOK CAS loop : non-atomicな構造体をオーディオループ外から更新する場合など ABA問題など各種の罠を回避できる farbot::NonRealtimeMutable<T>が便利
  5. オーディオスレッドと排他制御 double buffering (RTスレッドが更新するスペクトラムを non-RTスレッドが読む場合 etc.) farbot::RealtimeMutable<T>が便利 RTスレッドもnon-RTスレッドもデータを操作しうる場合 リングバッファを活用したfarbot FIFOが有用。ただオプションが多い

    : - single consumerかmulti consumerか? - single producerかmulti producerか? - ロック確保失敗時nullを返してもいいか? - etc... - 複数スレッドが変更するのはほぼ無理なので 変更は1つのスレッドに任せるべき
  6. 例外 throw - not RT-safe tryブロックに入って例外を投げないうちはRT-safe? -> YESっぽい - x86以外はRT-safe

    / x86: 実行時にunwindを動的に生成 関連: std::variantはRT-safeだがboost::variantはnot RT-safe - 例外発生時に例外オブジェクトを一時退避確保する挙動 MSのZero-overhead deterministic exceptionsのC++ draft
  7. その他 CPUキャッシュを活用できるようにコンテキストスイッチをなるべく回避する 型消去 : non RT-safe (std::any, std::function, ...) コルーチン:

    フレームメモリ確保が発生 rand() : 実装が「生成した数が重複しないようにロックする」可能性がある