当前的 2.4 和 2.5 版本中的 Linux 对称多处理(SMP)内核都支持超线程,并且已经在多线程基准测试程序中观测到了性能的提高(请参阅本文后面的 参考资料以获取含有更多详细信息的文章)。
本文提供了我们研究超线程(HT)对 Linux SMP 内核影响的结果。它比较了支持超线程的 Linux SMP 内核和不支持超线程的 Linux SMP 内核的性能。测试中的系统是支持多线程的、单 CPU Xeon。研究中所使用的基准测试程序涵盖了内核中受超线程影响的那些领域,比如调度程序、低级内核原语、文件服务器、网络和线程支持。
在 Linux 内核 2.4.19 上测试的结果说明了超线程技术可以使多线程应用程序的性能提高 30%。当前该技术使 Linux 内核 2.5.32 的性能提高幅度多达 51%。
Intel 的超线程技术通过复制、分区和共享 Intel NetBurst 微体系结构管道中的资源,使得一个物理处理器能包含两个逻辑处理器。
被复制的资源为两个线程创建了资源副本:
已分区的资源划分执行线程之间的资源:
共享的资源按需在两个正在执行的线程之间使用资源:
通常,每个物理处理器在一个处理器核心上都有一个体系结构状态,来为线程提供服务。使用了 HT,每个物理处理器在单个核心上就有两个体系结构状态,这使得物理处理器看起来象有两个逻辑处理器在为线程提供服务。系统 BIOS 列举出物理处理器中的每个体系结构状态。由于支持超线程的操作系统利用了逻辑处理器,因此这些操作系统就有两倍的资源可用于为线程提供服务。
在通用处理器中 Xeon 处理器最先实现同步多线程(SMT)(请参阅 参考资料以获取有关 Xeon 处理器系列的更多信息)。为达到在单一物理处理器上执行两个线程的目标,该处理器同时维持多个线程的上下文,这允许调度程序并发分派两个可能无关的线程。
操作系统(OS)将多个线程代码调度和分派给每个逻辑处理器,就如同在 SMP 系统中。没有分派线程时,相关的逻辑处理器保持空闲。
当将一个线程调度和分派给逻辑处理器 LP0 时,超线程技术利用必需的处理器资源来执行该线程。
当将第二个线程调度和分派给第二个逻辑处理器 LP1 时,就要按需为执行该线程而复制、划分或共享资源。每个处理器都在管道各点上进行选择,以控制和处理这些线程。当每个线程完成时,操作系统将未用的处理器置为空闲,释放资源让正在运行的处理器使用。
OS 将线程调度和分派给每个逻辑处理器,就好像是在双处理器或多处理器系统中进行的那样。当系统调度线程并将之引入到管道中时,按需利用资源以处理这两个线程。
Linux 内核将带有两个虚拟处理器的超线程处理器看成是一对真正的物理处理器。其结果是,处理 SMP 的调度程序也应该能处理超线程。Linux 内核 2.4.x 中的超线程支持始于 2.4.17,它包括了以下增强技术:
为评定超线程对 Linux 内核性能的影响,我们在包括 Intel Xeon 处理器(具有 HT 功能)的系统上测量了内核基准测试程序的性能。硬件是:支持 SMT 的单 CPU、1.6 GHz Xeon MP 处理器、2.5 GB RAM 和两个 9.2 GB SCSI 硬盘驱动器。测量的内核是配置和构建了支持 SMP 的现有内核 V2.4.19。内核超线程支持通过引导选项 acpismp=force
来指定使用超线程,并通过引导选项 noht
来指定不使用超线程。查看是否支持超线程可以通过使用命令 cat /proc/cpuinfo
,来显示处理器 0 和处理器 1 这两个处理器是否存在。请注意 清单 1 中用于 CPU 0 和 1 的 ht
标志。在不支持超线程的情况下,将只显示处理器 0 的数据。
清单 1. cat /proc/cpuinfo 的输出,显示超线程支持
processor : 0
vendor_id : GenuineIntel
cpu family : 15
model : 1
model name : Intel(R) Genuine CPU 1.60GHz
stepping : 1
cpu MHz : 1600.382
cache size : 256 KB
. . .
fpu : yes
fpu_exception: yes
cpuid level : 2
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr
pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht
tm
bogomips : 3191.60
processor : 1
vendor_id : GenuineIntel
cpu family : 15
model : 1
model name : Intel(R) Genuine CPU 1.60GHz
stepping : 1
cpu MHz : 1600.382
cache size : 256 KB
. . .
fpu : yes
fpu_exception: yes
cpuid level : 2
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr
pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht
tm
bogomips : 3198.15
为测量 Linux 内核性能,使用了 5 个基准测试程序:LMbench、AIM Benchmark Suite IX(AIM9)、chat、dbench 和 tbench。LMbench 基准测试程序对各种 Linux 应用程序编程接口(API)(例如,基本系统调用、上下文切换延迟和内存带宽)进行计时。AIM9 基准测试程序提供对用户应用程序工作负载的测量。chat 基准测试程序是模仿聊天室的客户机/服务器工作负载。dbench 基准测试程序是文件服务器工作负载,tbench 是 TCP 工作负载。chat、dbench 和 tbench 是多线程基准测试程序,而其它的则是单线程基准测试程序。
超线程对 Linux API 的影响通过 LMbench 来测量,LMbench 是包含一套带宽和延迟测量方法的微基准测试程序。这些影响中涉及了高速缓存文件读取、内存复制(bcopy)、内存读/写(和延迟)、管道、上下文切换、联网、文件系统的创建和删除、进程的创建、信号处理以及处理器时钟延迟。LMbench 着重测量以下内核组件:调度程序、进程管理、通信、联网、内存映射和文件系统。低级内核原语提供一个很好的、底层硬件能力和性能的指示器。
为研究超线程的效果,我们着重于延迟的测量,它测量消息控制的时间(换句话说,系统执行某个操作能有多快)。延迟的数量用“微秒/操作”进行记录。
表 1 显示了用 LMbench 进行测试的部分内核功能列表。每个数据点是三次运行的平均值,而且该数据已经作过收敛测试,以保证在相同的测试环境条件下它们是可再现的。通常,对于那些作为单线程运行的功能来说,有超线程和无超线程之间没有什么性能差别。然而,对于那些需要运行两个线程的测试(例如,管道延迟测试和三个进程延迟测试)来说,超线程似乎延长了它们的延迟时间。已配置的现有的 SMP 内核被标为 2419s。如果配置的内核不支持超线程,则将其标为 2419s-noht。若有超线程支持,则该内核被列为 2419s-ht。
表 1. 超线程对 Linux API 的影响
内核函数 | 2419s-noht | 2419s-ht | 加速 |
---|---|---|---|
简单的 syscall | 1.10 | 1.10 | 0% |
简单的 read | 1.49 | 1.49 | 0% |
简单的 write | 1.40 | 1.40 | 0% |
简单的 stat | 5.12 | 5.14 | 0% |
简单的 fstat | 1.50 | 1.50 | 0% |
简单的 open/close | 7.38 | 7.38 | 0% |
对 10 个 fd 的选择 | 5.41 | 5.41 | 0% |
对 10 个 tcp fd 的选择 | 5.69 | 5.70 | 0% |
信号处理程序安装 | 1.56 | 1.55 | 0% |
信号处理程序开销 | 4.29 | 4.27 | 0% |
管道延迟 | 11.16 | 11.31 | -1% |
进程 fork+exit | 190.75 | 198.84 | -4% |
进程 fork+execve | 581.55 | 617.11 | -6% |
进程 fork+/bin/sh -c | 3051.28 | 3118.08 | -2% |
注:数据用微秒表示:越小越好。 |
管道延迟的测试使用了两个通过 UNIX 管道进行通信的进程来测量经由套接字的进程间通信延迟。基准测试程序在这两个进程之间来回传送标记。性能下降幅度为 1%,小得可以忽略不计。
这三个进程测试包括了在 Linux 中进行的进程创建和执行。目的是测量创建基本控制线程所花去的时间。对于进程 fork+exit 测试来说,该数据表示将一个进程分成两个(几乎)相同的副本并退出其中一个所花的延迟时间。新进程就是这么创建的 - 但这不是非常有用,因为两个进程执行相同的操作。在这个测试中,超线程造成的性能下降幅度为 4%。
在进程 fork+execve 中,数据表示创建新进程并让该新进程运行新程序所花的时间。这是所有 shell(命令解释器)的内循环。由于超线程,可以看到这个测试性能下降幅度为 6%。
在进程 fork+/bin/sh -c 测试中,数据表示创建新进程并使该新进程运行新程序(通过让系统 shell 查找该程序并运行它)所要花去的时间。C 库接口就是这样实现对系统的调用。这个调用最常见,也最费时。在使用超线程的情况下,相对不用超线程而言,运行本测试慢了 2%。
AIM9 基准测试程序是单用户工作负载,旨在测量硬件和操作系统的性能。结果如表 2 所示。该基准测试程序中的大多数测试在使用超线程和不用超线程情况下执行性能都相同,只是同步文件操作和整数过滤(Integer Sieve)有所不同。同步随机磁盘写操作(Sync Random Disk Writes)、同步顺序磁盘写操作(Sync Sequential Disk Writes)和同步磁盘复制(Sync Disk Copies)这三个操作在使用超线程的情况下都慢了将近 35%。相反,在整数过滤的情况下使用超线程比不使用超线程速度提高了 60%。
表 2. 超线程对 AIM9 工作负载的影响
2419s-noht | 2419s-ht | 加速 | ||
---|---|---|---|---|
add_double | 每秒钟的双精度加法运算次数(千次) | 638361 | 637724 | 0% |
add_float | 每秒钟的单精度加法运算次数(千次) | 638400 | 637762 | 0% |
add_long | 每秒钟的长整型加法运算次数(千次) | 1479041 | 1479041 | 0% |
add_int | 每秒钟的整型加法运算次数(千次) | 1483549 | 1491017 | 1% |
add_short | 每秒钟的短整型加法运算次数(千次) | 1480800 | 1478400 | 0% |
creat-clo | 每秒钟的文件创建和关闭次数 | 129100 | 139700 | 8% |
page_test | 每秒钟的系统分配和换页数 | 161330 | 161840 | 0% |
brk_test | 每秒钟的系统内存分配次数 | 633466 | 635800 | 0% |
jmp_test | 每秒钟的非本地 goto 次数 | 8666900 | 8694800 | 0% |
signal_test | 每秒钟的信号陷阱数 | 142300 | 142900 | 0% |
exec_test | 每秒钟的程序装入次数 | 387 | 387 | 0% |
fork_test | 每秒钟的任务创建次数 | 2365 | 2447 | 3% |
link_test | 每秒钟的链接/解链对数 | 54142 | 59169 | 9% |
disk_rr | 每秒钟的随机磁盘读取数(K) | 85758 | 89510 | 4% |
disk_rw | 每秒钟的随机磁盘写入数(K) | 76800 | 78455 | 2% |
disk_rd | 每秒钟的顺序磁盘读取数(K) | 351904 | 356864 | 1% |
disk_wrt | 每秒钟的顺序磁盘写入数(K) | 154112 | 156359 | 1% |
disk_cp | 每秒钟的磁盘复制数(K) | 104343 | 106283 | 2% |
sync_disk_rw | 每秒钟的同步随机磁盘写入数(K) | 239 | 155 | -35% |
sync_disk_wrt | 每秒钟的同步顺序磁盘写入数(K) | 97 | 60 | -38% |
sync_disk_cp | 每秒钟的同步磁盘复制数(K) | 97 | 60 | -38% |
disk_src | 每秒钟的目录搜索次数 | 48915 | 48195 | -1% |
div_double | 每秒钟的双精度除法运算次数(千次) | 37162 | 37202 | 0% |
div_float | 每秒钟的单精度除法运算次数(千次) | 37125 | 37202 | 0% |
div_long | 每秒钟的长整型除法运算次数(千次) | 27305 | 27360 | 0% |
div_int | 每秒钟的整型除法运算次数(千次) | 27305 | 27332 | 0% |
div_short | 每秒钟的短整型除法运算次数(千次) | 27305 | 27360 | 0% |
fun_cal | 每秒钟的函数调用(没有参数)次数 | 30331268 | 30105600 | -1% |
fun_cal1 | 每秒钟的函数调用(1 个参数)次数 | 112435200 | 112844800 | 0% |
fun_cal2 | 每秒钟的函数调用(2 个参数)次数 | 97587200 | 97843200 | 0% |
fun_cal15 | 每秒钟的函数调用(15 个参数)次数 | 44748800 | 44800000 | 0% |
sieve | 每秒钟的整数过滤次数 | 15 | 24 | 60% |
mul_double | 每秒钟的双精度乘法运算次数(千次) | 456287 | 456743 | 0% |
mul_float | 每秒钟的单精度乘法运算次数(千次) | 456000 | 456743 | 0% |
mul_long | 每秒钟的长整型乘法运算次数(千次) | 167904 | 168168 | 0% |
mul_int | 每秒钟的整型乘法运算次数(千次) | 167976 | 168216 | 0% |
mul_short | 每秒钟的短整型乘法运算次数(千次) | 155730 | 155910 | 0% |
num_rtns_1 | 每秒钟的数字函数个数 | 92740 | 92920 | 0% |
trig_rtns | 每秒钟的三角函数个数 | 404000 | 405000 | 0% |
matrix_rtns | 每秒钟的点转换次数 | 875140 | 891300 | 2% |
array_rtns | 每秒钟解决的线性系统数 | 579 | 578 | 0% |
string_rtns | 每秒钟的字符串操作次数 | 2560 | 2564 | 0% |
mem_rtns_1 | 每秒钟的动态内存操作次数 | 982035 | 980019 | 0% |
mem_rtns_2 | 每秒钟的块内存操作次数 | 214590 | 215390 | 0% |
sort_rtns_1 | 每秒钟的排序操作次数 | 481 | 472 | -2% |
misc_rtns_1 | 每秒钟的辅助循环次数 | 7916 | 7864 | -1% |
dir_rtns_1 | 每秒钟的目录操作次数 | 2002000 | 2001000 | 0% |
shell_rtns_1 | 每秒钟的 Shell 脚本数 | 95 | 97 | 2% |
shell_rtns_2 | 每秒钟的 Shell 脚本数 | 95 | 96 | 1% |
shell_rtns_3 | 每秒钟的 Shell 脚本数 | 95 | 97 | 2% |
series_1 | 每秒钟的级数求值次数 | 3165270 | 3189630 | 1% |
shared_memory | 每秒钟的共享内存操作次数 | 174080 | 174220 | 0% |
tcp_test | 每秒钟的 TCP/IP 消息数 | 65835 | 66231 | 1% |
udp_test | 每秒钟的 UDP/IP 数据报数 | 111880 | 112150 | 0% |
fifo_test | 每秒钟的 FIFO 消息数 | 228920 | 228900 | 0% |
stream_pipe | 每秒钟的流管道消息数 | 170210 | 171060 | 0% |
dgram_pipe | 每秒钟的数据报管道消息数 | 168310 | 170560 | 1% |
pipe_cpy | 每秒钟的管道消息数 | 245090 | 243440 | -1% |
ram_copy | 每秒钟的内存到内存复制次数 | 490026708 | 492478668 | 1% |
为测量超线程对 Linux 多线程应用程序的影响,我们使用模仿聊天室的 chat 基准测试程序。该基准测试程序包括了客户机和服务器。该基准测试程序的客户机端将报告每秒钟所发送的消息数;聊天室和消息的数量将控制工作负载。该工作负载创建许多线程和 TCP/IP 连接,并发送和接收许多消息。它使用了以下缺省参数:
缺省情况下,每个聊天室有 20 位用户。10 个聊天室一共有 20x10 = 200 位用户。客户机将为聊天室里的每位用户创建至服务器的连接。由于我们有 200 位用户,所以我们将有 200 个到服务器的连接。现在,为聊天室中的每个用户(或连接)都创建了一个“发送”线程和一个“接收”线程。因此,“10 个聊天室”方案将创建 10x20x2 = 400 个客户机线程和 400 个服务器线程,一共是 800 个线程。但事实上不止这些。
每个客户机“发送”线程将把指定数量的消息发送给服务器。对于 10 个聊天室和 100 条消息而言,客户机将发送 10x20x100 = 20,000 条消息。服务器“接收”线程将接收相应数量的消息。聊天室服务器将把每条消息传回给聊天室中的其他用户。因而,对于 10 个聊天室和 100 条消息而言,服务器“发送”线程将发送 10x20x100x19 = 380,000 条消息。客户机“接收”线程将接收相应数量的消息。
通过命令行会话启动聊天服务器,以另一个命令行会话启动客户机,来开始测试。客户机模拟工作负载,并且其结果表示由该客户机所发送的消息数。当客户机结束其测试时,服务器循环并接受来自该客户机的其它启动消息。在我们的测量中,我们用 20、30、40 和 50 个聊天室来运行该基准测试程序。相应的连接和线程数如表 3 所示。
表 3. 所测试的聊天室和线程的数量
聊天室的 数量 | 连接的 数量 | 线程的 数量 | 所发送消息的 数量 | 所接收的消息的 数量 | 消息的 总数 |
---|---|---|---|---|---|
20 | 400 | 1,600 | 40,000 | 760,000 | 800,000 |
30 | 600 | 2,400 | 60,000 | 1,140,000 | 1,200,000 |
40 | 800 | 3,200 | 80,000 | 1,520,000 | 1,600,000 |
50 | 1000 | 4,000 | 100,000 | 1,900,000 | 2,000,000 |
表 4 显示了超线程对聊天工作负载性能的影响。每个数据点表示五次运行的几何平均数。数据集清楚地说明超线程根据聊天室的数量能将工作负载吞吐量提高 22% 到 28%。大体说来,基于 4 个聊天室样本的几何平均数,超线程将把聊天性能提高 24%。
表 4. 超线程对聊天吞吐量的影响
聊天室的数量 | 2419s-noht | 2419s-ht | 加速 |
---|---|---|---|
20 | 164,071 | 202,809 | 24% |
30 | 151,530 | 184,803 | 22% |
40 | 140,301 | 171,187 | 22% |
50 | 123,842 | 158,543 | 28% |
几何平均数 | 144,167 | 178,589 | 24% |
注:数据是客户机所发送的消息数:越大越好。 |
图 1. 超线程对聊天工作负载的影响
用 dbench 及其“同伴”测试 tbench 来测量超线程对文件服务器的影响。dbench 类似于 Ziff-Davis Media 基准程序中著名的 NetBench 基准测试程序,它让您在文件服务器处理来自客户机的网络文件请求时,测量其性能。但是,NetBench 要求精心设置实际的物理客户机,而 dbench 则模拟 90,000 个操作以产生相同的工作负载,这些操作通常由 NetBench 客户机通过嗅探称为 client.txt 的 4 MB 文件来运行。这个文件的内容是文件操作伪指令,例如 SMBopenx、SMBclose、SMBwritebraw 和 SMBgetatr 等。这些 I/O 调用符合服务器消息块(Server Message Block,SMB)协议,SAMBA 中的 SMBD 服务器在 netbench 运行中将产生该协议。SMB 协议被 Microsoft Windows 3.11、NT 和 95/98 用于共享磁盘和打印机。
在我们的测试中,一共使用了 18 种不同类型的 I/O 调用,包括打开文件、读、写、锁定、解锁、获取文件属性、设置文件属性、关闭、获取磁盘可用空间、获取文件时间、设置文件时间、“查找”打开、“查找”下一个、“查找”关闭、重命名文件、删除文件、创建新文件和清空文件缓冲区。
dbench 可以模拟任何数量的客户机,而不必进行物理设置。dbench 只产生文件系统负载,它没有联网调用。运行期间,每个客户机记录所移动的数据字节数并将该数除以移动该数据所需的时间量。然后累加所有的客户机吞吐量数以确定该服务器的总吞吐量。总的 I/O 吞吐量分数表示测试期间每秒钟所传送的兆字节数。这个测量说明该服务器对来自客户机的文件请求的处理质量。
dbench 非常适合于对超线程的测试,因为它对 CPU 和 I/O 调度程序创建了大量负载和活动。dbench 可以严格测试超线程支持多线程文件服务的能力,因为客户机同时创建和访问许多文件。每个客户机必须创建相当于大约 21 兆字节的测试数据文件。对于要运行 20 个客户机的测试,预计要大约 420 兆字节的数据。对于测量 Linux 文件系统所用的电梯算法性能,dbench 被认为是非常不错的测试方法。dbench 用于测试该算法的工作正确性,并测试电梯的反应是否足够快速。它还是很有趣的页面替换测试。
表 5 显示了 HT 对 dbench 工作负载的影响。每个数据点表示五次运行的几何平均数。数据说明了超线程将 dbench 的性能最少提高了 9%,最多提高了 29%。基于这五个测试方案的几何平均数,总体的提高幅度是 18%。
表 5. 超线程对 dbench 吞吐量的影响
客户机的数量 | 2419s-noht | 2419s-ht | 加速 |
---|---|---|---|
20 | 132.82 | 171.23 | 29% |
30 | 131.43 | 169.55 | 29% |
60 | 119.95 | 133.77 | 12% |
90 | 111.89 | 121.81 | 9% |
120 | 99.31 | 114.92 | 16% |
几何平均数 | 118.4 | 140.3 | 18% |
注:数据是用 MB/sec 表示的吞吐量:越大越好。 |
图 2. 超线程对 dbench 工作负载的影响
tbench 是类似于 dbench 的另一个文件服务器工作负载。但是,tbench 只产生 TCP 和进程负载。tbench 进行套接字调用,和 SMBD 在 netbench 负载下进行的调用相同,但是 tbench 不进行文件系统调用。tbench 背后的思想是将 SMBD 从 netbench 测试中消除掉,尽管可以使 SMBD 代码快速运行。tbench 的吞吐量结果告诉我们,如果我们消除所有文件系统 I/O 和 SMB 信息包处理,netbench 可以运行得有多快。tbench 被构建成 dbench 包的一部分。
表 6 描述了超线程对 tbench 工作负载的影响。和前面一样,每个数据点代表五次运行的几何平均数。超线程的确会提高 tbench 的吞吐量,提高幅度从 22% 到 31%。基于这五个测试方案的几何平均数,整体提高幅度为 27%。
表 6. 超线程对 tbench 吞吐量的影响
客户机的数量 | 2419s-noht | 2419s-ht | 加速 |
---|---|---|---|
20 | 60.98 | 79.86 | 31% |
30 | 59.94 | 77.82 | 30% |
60 | 55.85 | 70.19 | 26% |
90 | 48.45 | 58.88 | 22% |
120 | 37.85 | 47.92 | 27% |
几何平均数 | 51.84 | 65.77 | 27% |
注:这些数据是用 MB/sec 表示的吞吐量:越大越好。 |
图 3. 超线程对 tbench 工作负载的影响
Linux 内核 2.4.x 自 2.4.17 发行版起就支持 HT。内核 2.4.17 了解逻辑处理器,并将超线程处理器当作两个物理处理器。但是,仍然认为现有的内核 2.4.x 中所使用的调度程序还不成熟,因为它不能区别是两个逻辑处理器在争用资源,还是两个单独的物理处理器在争用资源。
Ingo Molnar 已经指出了当前调度程序出现错误的一些情况(请参阅 参考资料以获取链接)。请研究一下带有两个物理 CPU 的系统,每个 CPU 提供两个虚拟处理器。如果两个任务正在运行,当前调度程序会让它们同时在单个物理处理器上运行,即使将其中一个进程迁移到另一个物理 CPU 会得到好得多的性能。该调度程序还不明白:将进程从一个虚拟处理器迁移到另一个虚拟处理器(同一物理 CPU 上的逻辑 CPU)要比将进程在物理处理器之间进行迁移来得更省力(由于高速缓存装入)。
解决方案是更改运行队列的工作方式。2.5 调度程序在每个处理器中维持一个运行队列,并设法避免在队列之间移动任务。这种更改是让每个物理处理器拥有一个运行队列,它能将任务提供给所有的虚拟处理器。这样就比较清晰地说明,是什么产生了空闲 CPU(所有的虚拟处理器必须为空闲),产生的代码就会“神奇地实现”在超线程系统进行调度的需要。
除了 2.5 调度程序中运行队列的更改之外,还要进行其它必要的更改,以使 Linux 内核能够利用 HT 达到最佳性能。Molnar 讨论过的那些更改(请再次参阅 参考资料以获取有关此内容的更多信息)如下所示。
在撰写本文时,Molnar 已经提供了现有的内核 2.5.32 补丁程序,它通过引入共享运行队列(多个 CPU 可以共享同一个运行队列)的概念来实现上述所有更改。共享的、针对每个物理 CPU 的运行队列实现了上面所列的所有 HT 调度操作的需要。显然,这使调度和负载均衡变得复杂了,而且这对 SMP 和单处理器调度程序的影响仍然是未知的。
Linux 内核 2.5.32 中的更改旨在对带有两个以上 CPU 的 Xeon 系统产生影响,尤其是在负载均衡和线程亲缘性这些区域方面。由于硬件资源限制,我们只能测量其在我们单 CPU 测试环境中的影响。使用 2.4.19 中所使用的相同测试进程,我们在 2.5.32 上运行了三个工作负载:chat、dbench 和 tbench。对于 chat 而言,在有 40 个聊天室的情况下,HT 可以将速度提高 60%。整体提高幅度大约为 45%。对于 dbench 而言,27% 是最高的提高幅度,整体提高幅度大约为 12%。对于 tbench 而言,整体提高幅度大约为 35%。
表 7. 超线程对 Linux 内核 2.5.32 的影响
chat 工作负载 | |||
---|---|---|---|
聊天室的数量 | 2532s-noht | 2532s-ht | 加速 |
20 | 137,792 | 207,788 | 51% |
30 | 138,832 | 195,765 | 41% |
40 | 144,454 | 231,509 | 47% |
50 | 137,745 | 191,834 | 39% |
几何平均数 | 139,678 | 202,034 | 45% |
dbench 工作负载 | |||
客户机的数量 | 2532s-noht | 2532s-ht | 加速 |
20 | 142.02 | 180.87 | 27% |
30 | 129.63 | 141.19 | 9% |
60 | 84.76 | 86.02 | 1% |
90 | 67.89 | 70.37 | 4% |
120 | 57.44 | 70.59 | 23% |
几何平均数 | 90.54 | 101.76 | 12% |
tbench 工作负载 | |||
客户机的数量 | 2532s-noht | 2532s-ht | 加速 |
20 | 60.28 | 82.23 | 36% |
30 | 60.12 | 81.72 | 36% |
60 | 59.73 | 81.2 | 36% |
90 | 59.71 | 80.79 | 35% |
120 | 59.73 | 79.45 | 33% |
几何平均数 | 59.91 | 81.07 | 35% |
注:chat 数据是用 client/sec 表示的发送消息数;dbench 和 tbench 数据是用 MB/sec 表示的。 |
Intel Xeon 超线程对 Linux 内核和多线程应用程序肯定有积极作用。超线程产生的性能改进在现有的内核 2.4.19 中可高达 30%,在内核 2.5.32 中由于调度程序中运行队列支持和超线程支持的大量更改,其速度可提高 51%。
相关主题
转自:
https://www.ibm.com/developerworks/cn/linux/l-htl/index.html