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

SchemeのEphemeronとWeak Pairの説明

SchemeのEphemeronとWeak Pairの説明

Niyarin

June 25, 2020
Tweet

More Decks by Niyarin

Other Decks in Programming

Transcript

  1. Schemeの
    Ephemeron (と weak pair)
    Niyarin

    View Slide

  2. Ephemeronの概要
    About Ephemeron
    ・ R7RS large red/(SRFI 124)
    ・Weak-pairsの亜種
    ・オリジナルはSmalltalkに搭載された機能
    Smalltalk/vの作者の1人(George Bosworth)の発明
    ・ポータブルに実装できない

    View Slide

  3. 弱参照の雑な説明
    ・オブジェクトの生存判定に含まれない参照
    → 弱参照からのみ参照されているオブジェクトは回収できる
    (マークフェーズに辿らない/リファレンスカウントに含めない)
    ・例 ) Lispのsymbol intern table
    string->symbol したシンボルが不要になったらテーブルからも消したい

    View Slide

  4. Weakpair
    ・carが 弱参照でcdrが強参照なペア 
    通常のpairと違う点(Mit Schemeの例)
    ・回収済みかの述語の weak-pair/car?
    ・carが回収済みの場合、weak-car すると、#falseが帰る
    青:弱参照
    赤:強参照

    View Slide

  5. Weakpairで作るデータ構造1
    ・Weak list 
    ・Weak vector
    car部を弱参照のboxとして使う

    View Slide

  6. Weakpairで作るデータ構造2
    ・weak alist(flat)
    ・weak-pairと普通のpairを交互に配置した
    ・keyもvalも弱参照/keyが強参照でvalが弱参照も配置を変えるだけ

    View Slide

  7. Ephemeron
    「連想コンテナで今後assqされないkey-val対は不要」
    ・keyが弱参照でvalが強さが仕様しだいな参照を持つ
    (1) keyが回収できるなら、valへの参照はできなくなる(broken状態)
    (2) valからのみkeyが強参照できる場合でも回収できる
    Weak pairの問題
    pairの外でkeyがない(assqされない)が、
    valから強参照があれば、不要でもメモリに残り続ける

    View Slide

  8. Ephemeronで苦手なこと
    weak-listはできない↓ (finalizeがあれば少し事情が変わる)
    → あるcellのcarが回収された時点でcdrにいけなくなる
    ・weak containerの部品としては、weak-boxとしての使い方になる
    (通常のlistのcarにEphemeronをいれる)
    ・key-val対としては優秀

    View Slide

  9. Ephemeronの回収可能/不可能の例
    ・回収可能(broken)な例
    ・回収されない例

    View Slide

  10. Ephemeron処理系ごとの実装
    いくつかの実装は完全ではない
    ”valのみからの強参照の場合回収できる”ができない
    → Chibischeme、Sagittarius、Gauche etc.
    Racket や MIT/GNU Schemeはできている
    RacketやMIT/GNU Schemeではvalは弱参照扱い

    View Slide

  11. Ephemeron処理系ごとの実装
    ・自前のトレース系GCを持つ処理系は割とやるだけ
    "Ephemerons: A New Finalization Mechanism"に疑似コードがある
    ・Boehm GCは難しい
    弱参照:GC_GENERAL_REGISTER_DISAPPEARING_LINK
    ファイナライズ:GC_REGISTER_FINALIZER
    で、”keyが回収可能ならbrokenする”までは実装できる
    valからのみはこれだけではできない

    View Slide

  12. EphemeronとSchemeの回収の扱い
    R7RSのメモリの扱い
    “they are permitted to reclaim the storage occupied by an object.”
    → 「再利用を許可する」
    再利用は許可されているだけなので、普通のconsでも良い
    (define make-ephemeron cons)
    (define ephemeron-key car)
    (define ephemeron-datum cdr)
    (define (ephemeron-broken? _) #f)

    View Slide

  13. Sagittarius Schemeの現在の実装 
    ・Boehm GCを採用している処理系
    “keyが回収済みならvalを返さない”ことまではできる
    datumへのアクセスはkeyの生存判定を都度やって実現している
    (define (ephemeron-broken? e) (weak-box-empty? (ephemeron-key e)))
    (define (ephemeron-datum e)
    (and (not (ephemeron-broken? e)
    (%ephemeron-datum e)))

    View Slide

  14. よく知られているトレース系GCでの扱い
    value部で使われていても回収できる
    = value部以外で使われていなれば回収できる
    → Ephemeronの外側を最初にトレースすれば良い
    1.マークフェーズを行う
    ただしEphemeronに当たると、Ephemeron用Queueに入れて、中は辿らない
    2.Ephemeron用Queueでkeyが生きているものはvalue部について1を行う
    Ephemeron用Queueでkeyが回収可能なものはbrokenする
    ⇑はとても端折ったので、"Ephemerons: A New Finalization Mechanism"を見る
    ただし、疑似コードがSmalltalkだけど

    View Slide

  15. 実用例:手続きのキャッシュ
    ・引数2以降や結果が引数1を強参照していてもキャッシュから消せる
    ・引数のどれかが回収されたら、キャッシュは使えない
    → 途中のEphemeronがbrokenになっても問題ない
    ・(Improper listなのは、
    引数が生存している場合、結果は常に生存していて欲しいから)
    (引数と結果の組を保存して、
    毎回計算しなくてよくする)

    View Slide

  16. おわり
    ・Ephemeronは、キャッシュやテーブルの実装に役立つ
    ・SRFIにFinalize的なものが来ないかな...
    ・参照カウントを採用したSchemeのEphemeron採用例があったら楽しめたが..
    → そもそも参照カウントなScheme実装はあまり聞かない
    ・ポータブルでちゃんと実装するのは難しい(できない)ので、
    他のLisp方言の人たちはEphemeronが使えなくて悲しいでしょうね
    → Schemeは良いぞ 

    View Slide