使用新 PID 的輕量級程序行為
我一直在嘗試輕量級流程。基本上呼叫複製函式並為複製的 LWP 分配一個新的 PID。這很好用,它可以讓我辨識那些 LWP 的所有子執行緒。我遇到的一個小問題是性能。它退化了很多(處理速度減慢了 30%)。現在我正在閱讀可以安排 LWP 並為其分配優先級(我也沒有嘗試過)。這對錶演有幫助嗎?
我在執行 strace 時注意到的一件事是,Futex 的使用量激增了 8-10 倍。LWP會是造成這種情況的主要原因嗎?可以理解的部分是上下文切換的爆炸式增長,但我認為 LWP 共享相同的記憶體空間,所以 Futex 的使用量應該不會出現爆炸式增長。
在使用 LWP 或決定使用它們時,是否應遵循任何技巧或最佳實踐?
從性能的角度來看,分叉是更好還是更差的選擇?
經過幾天的測試,我發現了以下內容。
Futexes 來自執行緒之間共享記憶體緩衝區(不幸的是這是不可避免的),執行緒在相當高的頻率上執行數學模型。futex 直接影響執行延遲,但不是線性的,如果數據的頻率很高,它會更加依賴。
有可能避免使用記憶體池或類似的分配,因為我知道大多數數據的大小。這對執行和 CPU 負載有積極影響。
LWP 使用與父 PID 不同的 PID 複製,這在 linux 中是可以的,但在 pThreads 上不起作用。關於性能,由於 LWP 的原因,它會降低但不會顯著降低。共享記憶體資源正在產生一個更大的問題。
關於使用 jeMalloc、tcMalloc 和 locklessMalloc 建構應用程序,這些庫都沒有給我帶來競爭優勢。如果核心數為 4 或更高,則 TcMalloc 很好,如果記憶體應該很大,則 jeMalloc 很好。但對我來說,結果與多個執行場景的基線相差 +/- 1%。
關於將更多記憶體區域映射到對整體執行產生重大影響的程序中。FillBraden 在這方面是正確的,當執行開始或數據流增加數據量時,它對我們的打擊很大。我們使用記憶體池升級了那裡的行為。
包含一個測試系列以使用 SCHED_RR 執行應用程序,這也改進了執行。問題是它還對優先級的執行緒進行了更高的分級,因此這會產生影響。優點是我能夠在沒有超執行緒的情況下非常可靠地執行核心。原因是應用程序和模型的行為。由於未知的原因,超執行緒使事情變得相當混亂。
分叉單個模型有助於辨識哪些執行緒屬於哪個模型,但它不會給我們帶來任何執行速度的優勢。這絕對是一種交易,但也是一種解決方案,用於辨識執行不良的模型執行緒並修復它們。
我在執行 strace 時注意到的一件事是,Futex 的使用量激增了 8-10 倍。LWP會是造成這種情況的主要原因嗎?
$$ … $$,但我認為LWP共享相同的記憶體空間,所以Futex使用量應該不會出現爆炸式增長。
是的,使用 LWP 可能會增加 Futexes 的使用,因為它們實際上是針對這種情況,即共享相同記憶體的不同執行緒的同步。
當存在共享記憶體時,Futex 用於任何鎖操作的慢速路徑,LWP 或執行緒告訴核心阻塞它,直到通知鎖已被解除阻塞。
快速路徑使用原子操作(CPU 原子地增加或減少一個計數器,因此它可以檢測它是第一個鎖定還是最後一個解鎖),因此不需要在快速路徑上發出系統呼叫。
增加鎖競爭意味著會發生更多的 Futex 操作,這可能會影響性能,這不僅是因為系統呼叫本身,還因為當呼叫 Futex 時,這意味著一些 LWP 或執行緒正在休眠等待資源。
glibc 中的程式碼會意識到多執行緒或 LWP 的使用,因此即使您的程式碼中沒有顯式鎖,系統庫也會擁有它們,因此您可能會發生鎖爭用,可能會減慢速度您的程序如所述。
它退化了很多(處理速度減慢了 30%)。
當您有許多執行緒共享記憶體時,另一個因素是還有一些核心記憶體結構具有粗鎖並且也可能產生鎖爭用。
特別是,
mmap_sem
每次將更多記憶體區域映射到程序中時,都需要鎖定它以進行寫入。(特別是,malloc()
與好友分配更多記憶體可能會觸發此問題。)現在我正在閱讀可以安排 LWP 並為其分配優先級(我也沒有嘗試過)。這對錶演有幫助嗎?
可能……很難說。你必須進行基準測試。
如果您看到的是鎖爭用,並且如果它通過您的程式碼路徑進行概括(未本地化到單個或幾個 LWP),那麼它不太可能有幫助。
您可以使用該
perf
工具來幫助您了解 Linux 上一組程序的性能。它可以顯示熱點,也可以顯示核心熱點是否存在。在使用 LWP 或決定使用它們時,是否應遵循任何技巧或最佳實踐?
對於 LWP 或執行緒,當使用大量它們時,實現
malloc()
變得非常重要,因為存在與核心相關的問題(擴展記憶體映射會導致潛在的mmap_sem
.對於所有執行緒意味著您需要鎖定以保留它們的空間。)編寫了一些 malloc 庫以在使用大量執行緒的情況下提高性能。例如,tcmalloc或jemalloc。採用這些通常很簡單(只需連結一個額外的庫)並且如果這確實是您的瓶頸,可以產生很大的性能提升。與往常一樣,進行基準測試以了解這是否有幫助。
從性能的角度來看,分叉是更好還是更差的選擇?
可能更好。很難說,您需要進行基準測試以查看在您的特定情況下它是否更好。
與採用 LWP 一樣,您應該進行基準測試以判斷這是否真的值得。
如上所述,在 LWP 或執行緒之間使用共享記憶體(或有更多 LWP 或執行緒共享相同記憶體)會增加鎖爭用的可能性(即使您自己沒有顯式鎖,glibc 和核心也會。)所以LWP 很可能實際上會減慢您的速度。
我目睹了多執行緒應用程序太慢的情況。開發人員將其更改為使用單個執行緒而不是 40 個執行緒。該應用程序的速度突然提高了 1,000%。事實證明,它 90% 的時間都花在了鎖爭用上!