是的。进程和内核线程会被分配到处理器之间。用户空间线程则不会。
在 2.0 版本中,SMP 支持 hypersparc (SS20 等) 系统以及符合 Intel MP1.1/1.4 标准的 Intel 486、奔腾或更高版本的机器。Richard Jelinek 补充道:目前,系统已经过最多 4 个 CPU 的测试,MP 标准(以及 Linux)理论上允许最多 16 个 CPU。
UltraSparc、SparcServer、Alpha 和 PowerPC 机器的 SMP 支持在 2.2.x 版本中可用。
MIPS、m68k 和 ARM 不支持 SMP;后两者可能永远不会支持。
也就是说,一旦我拿到 SMP 机器,我就会开始 hack MIPS-SMP ...
(Matti Aarnio)Linux 实现线程的方式是在调度时将它们视为任何进程一样 - 线程只是恰好共享了源进程的几个资源;内存空间、文件描述符。有关部分解释,请参阅 clone(2)。
大多数 Linux 发行版不提供现成的支持 SMP 的内核,这意味着您必须自己制作一个。如果您还没有制作过自己的内核,这是一个学习如何制作内核的好理由。解释如何制作新内核超出了本文档的范围;有关更多信息,请参阅 Linux 内核 HOWTO。(C. Polisher)
配置内核,并对 CONFIG_SMP 回答 Y。
如果您使用 LILO,手头同时拥有 SMP 和非 SMP 内核镜像会很方便。编辑 /etc/lilo.conf 以创建一个名为 "linux-smp" 或其他名称的内核镜像条目。
下次编译内核时,当运行 SMP 内核时,编辑 linux/Makefile 并将 "MAKE=make" 更改为 "MAKE=make -jN"(其中 N = CPU 数量 + 1,或者如果您有大量内存/交换空间,您可以直接使用 "-j" 而不带数字)。请随意尝试这个选项。
当然,您应该记录每次构建所花费的时间 :-) 例如
make config time -v sh -c 'make dep ; make clean install modules modules_install'
如果您使用的是某些符合 Compaq MP 标准的机器,您需要在 BIOS 设置中将操作系统设置为 "Unix
在 2.0 内核系列(直到但不包括 2.1.132)中,取消注释主 Makefile (/usr/src/linux/Makefile
) 中的 SMP=1
行。
在 2.2 版本中,配置内核并对问题 “对称多处理支持” 回答 “是”(Michael Elizabeth Chastain)。
并且
通过配置 “字符设备” 菜单中的 “RTC 支持” 项来启用实时时钟支持(来自 Robert G. Brown)。请注意,插入 RTC 支持实际上并不能防止已知的 SMP 时钟漂移问题,但启用此功能可以防止在启动时读取时钟时出现死锁。Richard Jelinek 的一条注释还指出,激活增强型 RTC 对于在某些原始 Intel 主板上使第二个 CPU 工作(被识别)是必要的。
并且
(x86 内核)不要启用 APM(高级电源管理)! APM 和 SMP 不兼容,如果启用了 APM,您的系统几乎肯定(或至少可能 ;)
)在启动时崩溃(Jakob Oestergaard)。Alan Cox 证实了这一点:2.1.x 版本为 SMP 机器关闭了 APM。基本上,APM 在 SMP 系统存在的情况下是未定义的,任何事情都可能发生。
并且
(x86 内核)启用 “MTRR(内存类型范围寄存器)支持”。某些 BIOS 存在缺陷,因为它们没有为第二个处理器激活缓存内存。MTRR 支持包含解决此类处理器配置错误的代码。
当切换到 SMP 模式和从 SMP 模式切换时,您必须重建所有内核和内核模块。记住要 make modules
和 make modules_install
(来自 Alan Cox)。
如果您遇到模块加载错误,您可能没有重建和/或重新安装您的模块。此外,对于某些 2.2.x 内核,人们报告了从 SMP 编译切换回 UP(单处理器)时出现问题。要解决此问题,请保存您的 .config 文件,执行 make mrproper,恢复您的 .config 文件,然后重新制作您的内核(make dep 等)(Wade Hampton)。复制新内核后,不要忘记运行 lilo。
回顾
make config # or menuconfig or xconfig make dep make clean make bzImage # or whatever you want # copy the kernel image manually then RUN LILO # or make lilo make modules make modules_install
在 2.0 系列中,注释 主 Makefile (/usr/src/linux/Makefile) 中的 SMP=1
行。
在 2.2 系列中,配置内核并对问题 “对称多处理支持” 回答 “否”(Michael Elizabeth Chastain)。
当切换到 SMP 模式和从 SMP 模式切换时,您必须重建所有内核和内核模块。记住要 make modules
和 make modules_install
,并记住运行 lilo。请参阅上面关于可能配置问题的注释。
cat /proc/cpuinfo
典型输出(双 PentiumII)
processor : 0 cpu : 686 model : 3 vendor_id : GenuineIntel [...] bogomips : 267.06 processor : 1 cpu : 686 model : 3 vendor_id : GenuineIntel [...] bogomips : 267.06
Linux 内核版本 2.2 具有信号处理、中断和一些 I/O 细粒度锁定。其余部分正在逐步迁移。所有调度都是 SMP 安全的。
内核版本 2.3(下一个 2.4)具有真正的细粒度锁定。在 2.3 内核中,大型内核锁的使用基本上已经消失,所有主要的 Linux 内核子系统都是完全线程化的:网络、VFS、VM、IO、块/页缓存、调度、中断、信号等。(Ingo Molnar)
(Mark Hahn) 在内核的许多部分,2.2 和 2.4 之间几乎没有关系。最大的变化之一是 SMP - 不仅仅是锁的进化式细粒度,还有从根本上改进的 VM、内存管理、中断处理,这些基本上与 2.2 无关,相当革命性的网络变化(线程和零拷贝)等等。
简而言之,2.2 没有像 2.4 那样利用硬件。
否和是。没有办法强制进程到特定的 CPU 上,但 linux 调度器对每个进程都有处理器偏好,这倾向于将进程绑定到特定的 CPU。
是的。查看 PSET - Linux 内核的处理器集合
该项目的目标是为 Linux 制作一个源兼容且功能等效的 pset 版本(由 SGI 定义 - 部分从其 IRIX 6.4 内核中删除)。这使用户能够确定进程可以在哪个处理器或处理器集合上运行。可能的用途包括强制线程到不同的处理器、计时、安全性(“root” 专用 CPU?)以及可能更多。
它专注于 syscall sysmp()。此函数接受许多参数,这些参数确定请求的功能。功能包括
请将错误报告给 linux-smp@vger.kernel.org
。
如果您想衡量您的 SMP 系统的性能,您可以运行 Cameron MacKinnon 制作的一些测试,这些测试可在 http://www.phy.duke.edu/brahma/benchmarks.smp 找到。
另请查看 Bryant、Hartner、Qi 和 Venkitachalam 的这篇文章,该文章比较了 2.2 和 2.3/2.4 UP 和 SMP 内核:Linux� 内核 2.2.14 和 2.3.99 的 SMP 可扩展性比较 (Ray Bryant) (您还可以 在此处 找到副本)
如果您必须问这个问题,您可能不需要。 :)
通常,多处理器系统可以提供比单处理器系统更好的性能,但要实现任何收益,您需要考虑许多其他因素,而不仅仅是 CPU 的数量。例如,在给定的系统中,如果由于磁盘驱动器速度慢,处理器通常大部分时间处于空闲状态,那么该系统是 “输入/输出受限” 的,并且可能不会从额外的处理能力中受益。另一方面,如果一个系统有许多同时执行的进程,并且 CPU 利用率非常高,那么您很可能会实现系统性能的提高。SCSI 磁盘驱动器与多个处理器一起使用时可能非常有效,因为它们可以处理多个命令而不会占用 CPU。(C. Polisher)
这取决于应用程序,但很可能不会。SMP 增加了一些更快的单处理器系统不会产生的开销(Wade Hampton)。 :)
感谢 Samuel S. Chessman,这里有一些有用的实用程序
http://www.cs.inf.ethz.ch/~rauch/procps.html
基本上,它是 procps v1.12.2 (top, ps, et. al.) 和一些支持 SMP 的补丁。
对于 2.2.x,Gregory R. Warnes 制作了一个补丁,可在 http://queenbee.fhcrc.org/~warnes/procps 找到
xosview-1.5.1 支持 SMP。以及内核 2.1.85(包括)以上的 /proc/stat 文件中的 cpuX 条目。
xosview 的官方主页是:http://lore.ece.utexas.edu/~bgrayson/xosview.html
您会找到 Kumsup Lee 针对 2.2.x 内核打补丁的版本:http://www.ima.umn.edu/~klee/linux/xosview-1.6.1-5a1.tgz
顺便说一句,您无法使用 xosview 精确监控处理器调度,因为 xosview 本身会引起调度扰动。(H. Peter Anvin)
Rik van Riel 告诉我们原因
答案非常简单。基本上涉及 3 个进程
- CPU 占用大户(调度优先级低,因为它消耗 CPU)
- xosview
- X
CPU 占用大户在一个 CPU 上运行。然后 xosview 唤醒(在另一个 CPU 上)并开始向 X 发送命令,X 也随之唤醒。
由于 X 和 xosview 的优先级都比 CPU 占用大户高得多,因此 xosview 将在一个 CPU 上运行,X 将在另一个 CPU 上运行。
然后 xosview 停止运行,我们有一个空闲的 CPU --> Linux 将 CPU 占用大户移动到新空闲的 CPU(X 仍然在我们的占用大户之前运行的 CPU 上运行)。
使用
# make [modules|zImage|bzImages] MAKE="make -jX" where X=max number of processes. WARNING: This won't work for "make dep".
对于 2.2 类似内核,另请参阅文件 /usr/src/linux/Documentation/smp.txt
以获取具体说明。
顺便说一句,由于运行多个编译器允许内存充足的机器利用 I/O 引起的延迟期间浪费的 CPU 时间,make MAKE="make -j 2" -j 2
实际上甚至在单处理器系统上也有帮助(来自 Ralf B�chle)。
time
命令给出的时间不准确?(来自 Joel Marchand)在 2.0 系列中,time
命令给出的结果是错误的。用户 + 系统时间的总和是正确的 *但是* 用户时间和系统时间之间的分配是错误的。
更准确地说:“解释是,在引导 CPU 之外的处理器中花费的所有时间都计为系统时间。如果您对一个程序进行计时,将用户时间和系统时间相加,那么您的计时将几乎正确,除了还包括正确计算的系统时间”(Jakob �stergaard)。
此错误已在 2.2 内核中得到纠正。
由 Jakob �stergaard 编写。
本节旨在概述为 SMP Linux 编程多线程软件时哪些工作正常,哪些工作不正常。
由于 fork() 和 PVM/MPI 进程通常不共享内存,而是通过 IPC 或消息传递 API 进行通信,因此本节不再进一步描述它们。它们对于 SMP 来说不是非常特殊的,因为它们在单处理器计算机及其集群上的使用频率也一样多 - 甚至更多。
只有 POSIX 线程为我们提供了共享资源(尤其是内存)的多个线程。这是使 SMP 机器与众不同的地方,它允许多个处理器共享它们的内存。要使用 SMP 的两个(或更多 ;) 处理器,请使用内核线程库。一个好的库是 LinuxThreads,一个由 Xavier Leroy 制作的 pthread 库,现在已与 glibc2(又名 libc6)集成。较新的 Linux 发行版默认包含此库,因此您不必获取单独的软件包即可使用内核线程。
线程(和 POSIX 线程)的实现是应用程序级别的,并且不利用内核线程。这些线程包将线程保持在单个进程中,因此不利用 SMP。但是,它们对于许多应用程序都很有用,并且在单处理器系统上往往比内核线程运行得更快。
然而,多线程在 UN*X 世界中从未真正流行起来。由于某种原因,需要多个进程或线程的应用程序大多是使用 fork() 编写的。因此,当使用线程方法时,会遇到不兼容(未准备好线程)的库、编译器和调试器的问题。GNU/Linux 也不例外。希望接下来的几节能够阐明当前可能的情况和不可能的情况。
较旧的 C 库不是线程安全的。使用 GNU LibC (glibc),也称为 libc6 非常重要。当然,可以使用早期版本,但这会给您带来比升级系统更多的麻烦,好吧,可能吧 :)
如果您想使用 GDB 调试您的程序,请参阅下文。
GNU/Linux 有大量的编程语言可用,其中许多语言都可以通过某种方式使用线程(一些语言,如 Ada 和 Java,甚至在语言中将线程作为原始类型)。
但是,本节目前仅描述 C 和 C++。如果您有使用其他语言进行 SMP 编程的经验,请启发我们。
GNU C 和 C++ 以及 EGCS C 和 C++ 编译器都支持标准 C 库 (glibc) 的线程支持。但是,有一些问题
GNU 调试器 GDB 从 4.18 版本开始,应该可以正确处理线程。大多数 Linux 发行版都提供了一个打过补丁的、线程感知的 gdb。
无需以任何方式修补 glibc 即可使其与线程一起工作。如果您不需要调试软件(对于所有不是开发工作站的机器来说可能是正确的),则无需修补 glibc。
请注意,当使用多个线程时,核心转储没有任何用处。不知何故,核心转储附加到当前正在运行的线程之一,而不是整个程序。因此,无论何时调试任何内容,都请从调试器运行它。
提示: 如果您有一个线程运行失控,例如占用 100% 的 CPU 时间,并且您似乎无法弄清楚原因,这里有一个很好的方法来找出发生了什么:直接从 shell 运行程序,不使用 GDB。使线程失控。使用 top 获取进程的 PID。像 gdb program pid 这样运行 GDB。这将使 GDB 将自身附加到您指定的 PID 的进程,并停止线程。现在您有一个 GDB 会话,其中包含有问题的线程,可以使用 bt 等命令来查看发生了什么。
ElectricFence: 此库不是线程安全的。但是,通过在 ElectricFence 代码中插入互斥锁,应该可以在 SMP 环境中使其工作。
在 使用 Linux 进行并行处理 中可以找到许多有用的信息
另请查看 Linux 线程 FAQ
是的。对于程序,您应该查看:linux 上的多线程程序(我喜欢超链接,您知道吗? ;)
)
就库而言,有
感谢 David Buccarelli、Andreas Schiffler 和 Emil Briggs,它存在多线程版本(目前 [1998-05-11],有一个工作版本在某些 OpenGL 基准测试中提供了 5-30% 的加速)。多线程内容现在作为实验选项包含在常规 Mesa 发行版中。有关更多信息,请查看 Mesa 库
针对 Intel Linux 优化的 Pentium Pro BLAS 和 FFT
多线程 BLAS 例程目前不可用,但计划于 1998-05-27 发布双处理器库,有关详细信息,请参阅 Blas 新闻。
Emil Briggs,也是参与多线程 Mesa 的同一个人,也在开发多线程 GIMP 插件。有关更多信息,请查看 http://nemo.physics.ncsu.edu/~briggs/gimp/index.html。
(Randy Dunlap)Linux 支持 MPS(MP 规范)1.1 和 1.4 版本。
Linux 没有完全支持所有 MPS 1.4 版本。
经验表明,如果您的系统的 BIOS 中有 MP Spec. 1.1 版本选项,则 Linux 通常在 BIOS 配置为 MP Spec. 1.1 版本时效果最佳。我不明白 MP Spec. 版本应该对 Linux 有什么影响,但找出 BIOS 表呈现的差异,以确定为什么 Linux 在某些情况下 MP Spec. 1.4 版本失败,并修复 Linux 以使其无关紧要,这将是一项有趣的练习。
本文档总结了 MP Spec. 1.4 版本中的主要更改及其在 Linux 中的支持状态。
硬件必须支持一种操作模式,在该模式下,系统可以轻松地从 PIC 或虚拟线模式切换到对称 I/O 模式。当操作系统准备好切换到 MP 操作时,它会将 01H 写入 IMCR 寄存器(如果实现了该寄存器),并启用 I/O APIC 重定向表项。硬件不得要求软件执行任何其他操作即可完成到对称 I/O 模式的转换。
Linux 识别并支持此 MP 配置模式。
为了 PC/AT 兼容性,引导处理器必须支持 DOS 兼容的 FPU 执行和异常处理,同时在 PC/AT 兼容模式之一中运行。这意味着当系统处于 PIC 或虚拟线模式时,来自 BSP 的浮点错误信号必须路由到中断请求 13 信号 IRQ13。虽然来自应用程序处理器的浮点错误信号不需要路由到 IRQ13,但平台设计者可以选择连接两者。例如,在平台支持启动期间动态选择 BSP 的情况下,将来自应用程序处理器的浮点错误信号连接到 IRQ13 可能很有用。
在对称模式下,兼容系统仅支持片上浮点单元,并通过中断向量 16 发送错误信号。当系统处于对称模式时,操作系统必须使用中断向量 16 来管理浮点异常。
除了在不具备 SMP 功能的真正 i386 处理器系统中,Linux 根本不使用浮点中断。[在这些系统中,如果它们以 PC/AT 兼容的方式连接 FPU 异常线,则会执行 #MF 异常可用性的运行时检查。如果 #MF 异常可用,则 Linux 会处理此中断(如果发生)。(Maciej W. Rozycki)
Linux 支持多 I/O APIC。
此表在 MPS 1.4 版本中成为可选。如果该表不存在,则应使用默认配置之一。还为其添加了一个扩展部分,用于新的表条目类型。
Linux 支持可选的 MP 配置表,如果 MP 配置表不存在,则使用默认配置。
Linux 通过跳过扩展部分表条目(如果找到)来容忍它们。扩展表条目中的数据未使用。
MP Spec. 1.4 版本的新字段或更改字段
定义了系统地址空间映射、总线层级描述符和兼容总线地址空间修饰符的条目类型。
Linux 跳过(不使用)这些扩展 MP 配置表条目。显然,这对于任何出货系统都不是至关重要的。