Clojure世界: STM的統計
年前一篇blog提過,寫了一個stm-profiler用於統計clojure STM的運行狀況,放在了github上:
https://github.com/killme2008/stm-profiler STM的事務在遇到寫衝突(多個事務寫同一個ref的時候)就會回滾事務並重試,通過stm-profiler你可以查看事務的重試次數,重試原因,以及每個reference的使用情況。使用很簡單,在lein的project.clj引用stm-profiler:
[stm-profiler "1.0.2-SNAPSHOT"]
注意,目前stm profiler僅支持clojure 1.3。 我們寫一個簡單例子:
(use 'stm)
(def a (ref 1)) (def b (ref 2)) (dotimes [_ 100] (future (dosync (alter a + 1) (alter b - 1)))) (Thread/sleep 1000) (prn @a) (prn @b) (Thread/sleep 1000) (prn "stm statistics" (stm-stats)) (prn "reference a statistics" (ref-stats a)) (prn "reference b statistics" (ref-stats b)) 定義了兩個ref:a和b,然後用future啟動100個線程並發地發起同一個事務操作,對a加一,對b減一。最後打印a和b的值,使用stm-stats函數獲取stm的統計信息並打印,使用ref-stats獲取a和b兩個reference的統計信息並打印。 運行這個例子,在啟動的時候會有些警告信息,忽略即可(主要是因為stm profiler重新定義了一些跟STM相關的函數和宏,如dosync等,但是僅僅是添加了統計功能,並沒有修改他們原本的功能)。 在我機器上的一次輸出:
101
-98 "stm statistics" {"(alter a + 1)(alter b - 1)" {:not-running 11, :average-retry 5, :total-cost 1233, :get-fault 44, :barge-fail 224, :change-committed 227, :total-times 100, :average-cost 12}} "reference a statistics" {"(alter a + 1)(alter b - 1)" {:alter 609, :get-fault 44, :barge-fail 224, :change-committed 227}} "reference b statistics" {"(alter a + 1)(alter b - 1)" {:alter 114, :not-running 11}} a和b的結果都沒問題。重點看打印的統計信息,(stm-stats)的輸出結果是:
{"(alter a + 1)(alter b - 1)" {:not-running 11, :average-retry 5, :total-cost 1233, :get-fault 44, :barge-fail 224, :change-committed 227, :total-times 100, :average-cost 12}}
這個結果是一個map,key是事務的form,而value就是該form的統計信息,也是一個map,具體各項的含義如下:
從輸出結果來看,這麼簡單的一個事務操作,每次事務要成功平均都需要經過5次的重試,最大的原因是因為ref的值在事務中被其他事務更改了,或者嚐試打斷其他正在運行的事務失敗而重試。關於clojure STM的具體原理推薦看這篇文章《Software transactional memory》。STM不是完美的,事務重試和保存每個reference的曆史版本的代價都不低。 再看(ref-stats a)的輸出:
{"(alter a + 1)(alter b - 1)" {:alter 609, :get-fault 44, :barge-fail 224, :change-committed 227}}
可以看到a在所有事務中的統計信息,返回的結果同樣是個map,key是使用了a的事務,value是具體的統計信息。各項的含義類似上表,不過這裏精確到了具體的reference。其中alter項是指對a調用alter函數了609次。ref-stats會輸出所有在事務中調用了a的函數的調用次數。通過stm profiler你可以分析具體每個事務的執行狀況,甚至每個reference的運行狀況,查找熱點事務和熱點reference等。stm-profiler還不完善,目前還不支持1.2(1.4測試是可以的)。希望有興趣的朋友加入進來一起完善。 文章轉自莊周夢蝶 ,原文發布時間2012-02-09
|
最後更新:2017-05-18 20:36:04