为什么禁用超线程会使我的服务器变慢?

S.G*_*ami 14 hyperthreading

我有一个主要运行 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"
Run Code Online (Sandbox Code Playgroud)
  • 使用超线程:
? 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
Run Code Online (Sandbox Code Playgroud)

gnome-system-monitor在测试运行时报告了 Ruby 25% 的 CPU 使用率。

  • 没有超线程:

[# 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
Run Code Online (Sandbox Code Playgroud)

gnome-system-monitor在测试运行时报告了 Ruby 50% 的 CPU 使用率。


我什至在我的笔记本电脑上进行了测试,这大约是在我的电脑上花费的时间的两倍。但结果是相同的:禁用超线程并不能帮助进程做得更好。更糟糕的是,我的笔记本电脑在处理多任务时会变慢。

因此,在非超线程模式下,Ruby 使用的 CPU 能力是超线程模式的 2 倍。但是为什么完成相同的任务仍然需要相同的时间?

sho*_*hok 46

你的Ruby程序并没有与HT禁用运行时,使用2倍的CPU时间。相反,当它最大化两个总内核中的一个内核时,gnome-system-monitor将报告为 50% 的利用率。如果由于 HT,系统报告总共有四个核心,则四分之一个核心将是 25%。

禁用 HT 确实会导致结果发生更多变化,因为可用资源较少:最近的 Intel(或 AMD)内核非常广泛,因此额外的线程通常有助于将总性能提高 10-20%。如果在测试运行期间自动执行某些后台进程,则没有 HT 的系统容易出现更多差异和更低的总吞吐量。

  • 值得注意的是,许多 CPU 监视器相对于单个内核读取,在这些监视器中,您经常会看到一个进程占用超过 100% 的 CPU,因为它是线程化的,并且利用了超过一个完整内核的 CPU 时间。如果在解释结果时了解显示器正在读取的内容很重要。 (3认同)