我們有幾個延遲敏感的「管道」風格的程序,在一個Linux內核上運行時,其性能會有明顯的下降。尤其是,我們發現2.6.9 CentOS 4.x(RHEL4)內核的性能更好,而CentOS 5.x(RHEL5)2.6.18內核的性能更差。多核系統上的Linux線程調度差異?
「管道」程序,我的意思是一個有多個線程。多線程處理共享數據。每個線程之間都有一個隊列。因此,線程A獲取數據,將數據推入Qab,線程B從Qab中抽取,執行一些處理,然後推入Qbc,線程C從Qbc中抽取等等。初始數據來自網絡(由第三方生成)。
我們基本上測量從接收數據到最後一個線程執行任務的時間。在我們的應用程序中,當從CentOS 4移至CentOS 5時,我們看到從20微秒到50微秒的增加。
我已經使用了幾種分析我們應用程序的方法,並確定在CentOS 5上增加的延遲來自隊列操作(特別是彈出)。
但是,通過使用taskset將程序綁定到可用內核的子集,我可以提高CentOS 5的性能(與CentOS 4相同)。
因此,在CentOS 4和5之間,引起線程調度不同(對於我們的應用程序來說這是不理想的)的一些改變(可能是內核)。
雖然我可以使用taskset(或通過sched_setaffinity()在代碼中)「解決」這個問題,但我的首選是不必這樣做。我希望有某種內核可調參數(或者可能是可調參數的集合),其默認值在版本之間進行了更改。
任何人都有這方面的經驗?也許還有一些地方需要調查?
更新:在這種特殊情況下,通過來自服務器供應商(Dell)的BIOS更新解決了此問題。我在這一張上拉了一會兒頭髮。直到我回到基礎,並檢查了我的供應商的BIOS更新。可疑的是,其中一項更新表示「在最佳性能模式下提高性能」。一旦我升級了BIOS,CentOS 5的速度更快 - 一般來說,但特別是在我的隊列測試和實際生產運行中。
出隊操作僅對較慢的情況(即較新的RHEL5內核)產生性能影響。根據我的實驗,我對此的最佳猜測解釋是不同的線程在覈心上進行調度,從而失去緩存優勢。我忘了提及,我的機器具有雙核四核CPU封裝。直觀地說,如果在兩個CPU _packages_中調度的兩個線程之間存在共享隊列,那麼性能將會很糟糕。但是,這只是一個猜測,因此是一個問題。 :) – Matt 2011-05-24 17:27:17
我明白了。現在你提到它了,我記得有一次故意填充一個線程間通信對象,以確保兩個實例不能位於同一個緩存線上。如果涉及到兩個離散包,我認爲事情會變得更加嚴峻:( – 2011-05-24 17:33:10
是的 - 我不知道有多少數據在您的線程間類/ struct/whatever中,但是您可以在啓動時創建它們的池,以確保它們的大小是4k還是在頁面邊界上?這應該減少緩存刷新,因爲沒有兩個內核會在同一頁數據上運行。 – 2011-05-24 17:41:49