Hyperthreading

為什麼禁用超執行緒會使我的伺服器變慢?

  • March 5, 2020

我有一個主要執行 Ruby 腳本的伺服器。因為 Ruby (2.7) 有一個 GIL,所以它是單執行緒的。

我的電腦(伺服器)有一個 Intel i3 雙核處理器,但由於超執行緒,我看到了 4 個核心。Ruby 在重負載下僅使用 25% 的 CPU。我想看看禁用超執行緒是否有利於在單執行緒上執行的程式語言。

此外,我的伺服器正在執行一個非常小的桌面環境,它使用的 CPU 不超過 2%。所以我想讓大部分資源都可用於 Ruby。我做了一個基準測試,看看我是否真的通過禁用超執行緒來提高性能。


基準:

我編寫了一個簡單的 Ruby 腳本,它執行一個 while 循環並將循環計數器的值與另一個變數相加。該程序應使用 100% 的 CPU 核心:

#!/usr/bin/env ruby
$-v = true

LOOPS = ENV['N'].to_i.then { |x| x < 1 ? 100_000_000 : x } + 1
i, j, t = 0, 0, Time.now

puts "Counting till #{LOOPS - 1} and adding values to V..."
while (i += 1) < LOOPS
   if i % 10000 == 0
       e = Time.now - t
       r = LOOPS.*(e)./(i).-(e).round(2)
       print "\e[2KN: #{i} | Done: #{i.*(100) / LOOPS}% | Elapsed: #{e.round(2)}s | Estimated Rem: #{r}s\r"
   end

   j += i
end

puts "\nV = #{j}\nTime: #{(Time.now).-(t).round(2)}s"
  • 使用超執行緒:
⮚ ruby p.rb
Counting till 100000000 and adding values to V...
N: 100000000 | Done: 99% | Elapsed: 4.55s | Estimated Rem: 0.0s
V = 5000000050000000
Time: 4.55s

⮚ ruby p.rb
Counting till 100000000 and adding values to V...
N: 100000000 | Done: 99% | Elapsed: 4.54s | Estimated Rem: 0.0s
V = 5000000050000000
Time: 4.54s

⮚ ruby p.rb
Counting till 100000000 and adding values to V...
N: 100000000 | Done: 99% | Elapsed: 4.67s | Estimated Rem: 0.0s
V = 5000000050000000
Time: 4.67s

gnome-system-monitor在測試執行時報告 Ruby 的 CPU 使用率為 25%。

  • 沒有超執行緒:

[# echo 0 | tee /sys/devices/system/cpu/cpu{2,3}/online用於禁用超執行緒]

⮚ ruby p.rb
Counting till 100000000 and adding values to V...
N: 100000000 | Done: 99% | Elapsed: 4.72s | Estimated Rem: 0.0s
V = 5000000050000000
Time: 4.72s

⮚ ruby p.rb
Counting till 100000000 and adding values to V...
N: 100000000 | Done: 99% | Elapsed: 4.54s | Estimated Rem: 0.0s
V = 5000000050000000
Time: 4.54s

⮚ ruby p.rb
Counting till 100000000 and adding values to V...
N: 100000000 | Done: 99% | Elapsed: 4.56s | Estimated Rem: 0.0s
V = 5000000050000000
Time: 4.56s

gnome-system-monitor在測試執行時報告 Ruby 的 CPU 使用率為 50%。


我什至在我的筆記型電腦上執行了測試,它所花費的時間大約是我電腦上的兩倍。但結果是相同的:禁用超執行緒並不能幫助程序做得更好。更糟糕的是,我的筆記型電腦在多任務處理時會變慢一些。

因此,在非超執行緒模式下,Ruby 使用的 CPU 功率是超執行緒模式的 2 倍。但是為什麼完成同樣的任務仍然需要同樣的時間呢?

在禁用 HT 的情況下執行時,您的 Ruby 程序沒有**使用2 倍的 CPU 時間。**相反,當它最大化兩個核心中的一個核心時,gnome-system-monitor將報告為 50% 的使用率。如果由於 HT 的原因,系統報告總共四個核心,那麼四分之一的核心將是 25%。

禁用 HT 確實會導致結果的更多變化,因為可用的資源更少:最近的 Intel(或 AMD)核心非常寬,因​​此額外的執行緒通常有助於提高 10-20% 的總性能。如果在測試執行期間自動執行了一些後台程序,則沒有 HT 的系統容易出現更大的差異和更低的總吞吐量。

引用自:https://serverfault.com/questions/1005612