| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | ||||||||||||||||||||||||||
2 | 測試環境及方法 | |||||||||||||||||||||||||
3 | Hardware | HP ProLiant DL380p Gen8 / E5-2680 v2 @ 2.80GHz | ||||||||||||||||||||||||
4 | OS | ESXi 6.5.0 Update 1 (Build 5969303) / VM: ubuntu16 4.4.0-62-generic (分配 8 cores) | ||||||||||||||||||||||||
5 | 測試 5 次,取平均值最低的那次。 | |||||||||||||||||||||||||
6 | 延遲數據使用所有 threads 合併後計算的結果。 | |||||||||||||||||||||||||
7 | 使用 /usr/bin/time -v 測量資源使用狀況。 | |||||||||||||||||||||||||
8 | ||||||||||||||||||||||||||
9 | ||||||||||||||||||||||||||
10 | 比較對象: | |||||||||||||||||||||||||
11 | fon9 | https://github.com/fonwin/libfon9 | ||||||||||||||||||||||||
12 | * 立即格式化,格式化之後的字串丟到 locked buffer,在另一 thread 寫檔。 | |||||||||||||||||||||||||
13 | * lock 機制使用: Mutex = SpinMutex<YieldSleepPolicy>; | |||||||||||||||||||||||||
14 | * 大約 [每2萬筆] 或 [每秒] 觸發一次寫檔通知。 | |||||||||||||||||||||||||
15 | ||||||||||||||||||||||||||
16 | spdlog | https://github.com/gabime/spdlog | ||||||||||||||||||||||||
17 | * 使用 libfmt 立即格式化,格式化的程式在: | |||||||||||||||||||||||||
18 | * include/spdlog/details/logger_impl.h | |||||||||||||||||||||||||
19 | * spdlog::logger::log(...) | |||||||||||||||||||||||||
20 | * 使用 lock-free bounded queue 處理 async_msg | |||||||||||||||||||||||||
21 | * 但是 async_msg 用了 2 個 std::string (這是成本很高, 但容易被忽視的物件) | |||||||||||||||||||||||||
22 | * include/spdlog/details/async_log_helper.h | |||||||||||||||||||||||||
23 | * struct async_msg; | |||||||||||||||||||||||||
24 | * logger_name, txt; | |||||||||||||||||||||||||
25 | * 為了避免 std::string 造成效率的干擾,所以測試時在 `async_msg(const details::log_msg &m);` **建構時不填入 logger_name 及 txt ** 。 | |||||||||||||||||||||||||
26 | * spdlog::set_async_mode(1048576); | |||||||||||||||||||||||||
27 | * spdlog::create<spdlog::sinks::simple_file_sink_mt>("file_logger", "/tmp/spd-async.txt", false); | |||||||||||||||||||||||||
28 | ||||||||||||||||||||||||||
29 | mal : mini-async-log | https://github.com/RafaGago/mini-async-log | ||||||||||||||||||||||||
30 | * 使用 lazy format + lock-free (bounded queue) + (node based mpsc queue)。 | |||||||||||||||||||||||||
31 | * [轉字串] & [寫 log 檔] 的工作放在獨立的 thread 裡面。 | |||||||||||||||||||||||||
32 | queue 使用 2 個機制 (mal_cfg.queue.can_use_heap_q = true;): (1) 在 log entry 小於 64B && bounded_queue 空間足夠,則直接放到 bounded_queue (2) 否則分配記憶體來儲存 log entry,然後存入 node base mpsc queue => 所以一旦單一 log entry 超過 64B,或瞬間資料量超過 bounded queue size,效能就會降低。 | |||||||||||||||||||||||||
33 | lazy format 還有一個好處是:format 的程式碼集中在輸出 thread,可降低主線的 CPU code cache 負擔。 | |||||||||||||||||||||||||
34 | ||||||||||||||||||||||||||
35 | NanoLog | https://github.com/Iyengar111/NanoLog | ||||||||||||||||||||||||
36 | * 使用 lazy format + lock-free bounded queue。 | |||||||||||||||||||||||||
37 | * 由於 mal 的效能比 NanoLog 好很多,所以 NanoLog 就不列入評比了。 | |||||||||||||||||||||||||
38 | ||||||||||||||||||||||||||
39 | ||||||||||||||||||||||||||
40 | ||||||||||||||||||||||||||
41 | 結論: | |||||||||||||||||||||||||
42 | 這裡只是從表現數據來猜想可能的原因,如果要確定成因,要有更嚴謹的研究及測試才行。 | |||||||||||||||||||||||||
43 | ||||||||||||||||||||||||||
44 | lock 表現尚可,但隨著碰撞增加,延遲也增加。 | |||||||||||||||||||||||||
45 | lock-free queue 大法好,排除其他干擾之後,表現穩定,即使在 thread 數量增加的情境,仍有穩定 (且低延遲) 的表現。 | |||||||||||||||||||||||||
46 | ||||||||||||||||||||||||||
47 | 看來 fon9 也要好好考慮 lock-free 機制了。 | |||||||||||||||||||||||||
48 | ||||||||||||||||||||||||||
49 | ||||||||||||||||||||||||||
50 | ||||||||||||||||||||||||||
51 | ||||||||||||||||||||||||||
52 | ||||||||||||||||||||||||||
53 | ||||||||||||||||||||||||||
54 | ||||||||||||||||||||||||||
55 | ||||||||||||||||||||||||||
56 | ||||||||||||||||||||||||||
57 | ||||||||||||||||||||||||||
58 | ||||||||||||||||||||||||||
59 | ||||||||||||||||||||||||||
60 | ||||||||||||||||||||||||||
61 | ||||||||||||||||||||||||||
62 | ||||||||||||||||||||||||||
63 | ||||||||||||||||||||||||||
64 | ||||||||||||||||||||||||||
65 | ||||||||||||||||||||||||||
66 | ||||||||||||||||||||||||||
67 | ||||||||||||||||||||||||||
68 | ||||||||||||||||||||||||||
69 | ||||||||||||||||||||||||||
70 | ||||||||||||||||||||||||||
71 | ||||||||||||||||||||||||||
72 | ||||||||||||||||||||||||||
73 | ||||||||||||||||||||||||||
74 | ||||||||||||||||||||||||||
75 | ||||||||||||||||||||||||||
76 | ||||||||||||||||||||||||||
77 | ||||||||||||||||||||||||||
78 | ||||||||||||||||||||||||||
79 | ||||||||||||||||||||||||||
80 | ||||||||||||||||||||||||||
81 | ||||||||||||||||||||||||||
82 | ||||||||||||||||||||||||||
83 | ||||||||||||||||||||||||||
84 | ||||||||||||||||||||||||||
85 | ||||||||||||||||||||||||||
86 | ||||||||||||||||||||||||||
87 | ||||||||||||||||||||||||||
88 | ||||||||||||||||||||||||||
89 | ||||||||||||||||||||||||||
90 | ||||||||||||||||||||||||||
91 | ||||||||||||||||||||||||||
92 | ||||||||||||||||||||||||||
93 | ||||||||||||||||||||||||||
94 | ||||||||||||||||||||||||||
95 | ||||||||||||||||||||||||||
96 | ||||||||||||||||||||||||||
97 | ||||||||||||||||||||||||||
98 | ||||||||||||||||||||||||||
99 | ||||||||||||||||||||||||||
100 |