1

这很难说/问,所以请多多包涵:

当我们看到汇编的输出时,这就是将在 CPU 的核心上执行的内容。但是,如果 CPU 有多个内核,那么所有程序集是否都在同一个内核上执行?来自同一程序的程序集何时开始在不同的内核上执行?

所以如果我有(汇编伪):

ADD x, y, z
SUB p, x, q

我怎么知道 ADD 和 SUB 是否会在同一个内核上执行?这与亲和力有关吗?我认为亲和力只将进程固定到 CPU,而不是核心?

我问这个是因为我想尝试了解您是否可以合理地预测连续的汇编指令是否在同一个内核上执行,以及我是否可以控制它们只在同一个内核上执行。我试图了解如何决定将执行相同的程序代码从一个内核更改为不同的内核?

如果程序集可以将执行(即使使用亲和性)从 CPUA Core1 更改为 Core2,QPI 链接速度是否会在此处生效?以及缓存是否在不同的 CPU 内核之间共享?

4

3 回答 3

2

这是一个粗略的概述,希望能为您提供所需的详细信息。

  1. 汇编代码被翻译成机器代码;即二进制数据,由 CPU 运行。

  2. CPU与多核处理器上的核心相同;即 CPU 与处理器(芯片)不同。

  3. 每个 CPU 都有一个指令指针,指向下一条要执行的指令。每执行一条指令都会递增。

因此,在多核处理器中,每个核心都有一个指令指针。为了支持比可用 CPU(或内核)更多的进程,操作系统将定期中断正在运行的进程并存储它们的状态(包括指令指针)。然后它将恢复已中断进程的状态并让它们执行一段时间。

继续执行的核心由操作系统决定,并由正在运行的线程的亲和性(可能还有其他一些设置)控制。

所以要回答你的问题,没有办法知道两个相邻的汇编语句是否会在同一个核心上运行。

于 2013-03-16T14:31:48.187 回答
2

我主要是在谈论 Linux。但我想我所说的应该适用于其他操作系统。但是,如果无法访问 Windows 源代码,没有人可以可靠地详细说明它的行为方式

我认为您对计算机正在做什么的“抽象”是不够的。基本上,一个(单线程)进程(或只是一个线程)正在某个“虚拟”CPU 上运行,其指令集是未经授权的 x86 机器指令,通过系统调用(通常是通过特殊指令)进入内核的能力得到增强像SYSENTER)。因此,从应用程序的角度来看,对linux 内核的系统调用是“原子的”。看到这个那个答案。

事实上,处理器正在(在任意时刻)获得一些中断(在 Linux 上,cat /proc/interrupts以一秒的延迟重复两次将显示它被中断的频率,基本上每秒数千次),这些中断由核心。内核正在抢先调度任务(例如线程或进程)(它们可以随时被内核中断和重新启动)。

从应用程序的角度来看,中断并不真正存在(但内核可以向进程发送信号)。

内核、中断和缓存由硬件和/或内核处理,因此从应用程序的角度来看,它们并不真正存在——除非“减慢”进程。缓存一致性主要在硬件中处理,并且乱序执行使得给定的 - 甚至是微小的 - 二进制程序的执行时间不可预测。(换句话说,您无法准确地预测某个给定例程或循环需要多少毫秒;您只能动态地测量它;阅读有关最坏情况执行时间的更多信息)。

阅读Advanced Linux Programming一书和Linux Assembly Howto会有所帮助。

于 2013-03-16T15:01:29.543 回答
1

您通常无法预测每条单独指令将在何处执行。只要单个线程连续执行,它就会在同一个核心/处理器内运行,但您无法预测线程将在哪条指令上被切换。操作系统会根据系统的工作负载和优先级等因素做出决定,决定何时将其切换回来,以及将其放置在哪个内核/处理器上。

您通常可以专门向操作系统请求线程应始终在同一内核上运行,这称为亲和力。这通常是一个坏主意,只有在绝对必要时才应该这样做,因为它剥夺了操作系统根据工作负载决定在哪里做什么的灵活性;亲和力几乎总是会导致性能下降。

请求处理器亲和性是一个特殊的请求,需要特殊的证据来证明它会带来更好的性能。不要试图超越操作系统;操作系统知道您不知道的有关当前运行环境的事情。

于 2013-03-16T14:52:23.730 回答