9

我正在为我的内核做一些输入缓冲区的工作,我有一些问题。在双核机器上,我知道可以同时运行多个“进程”。我不知道操作系统和各个程序如何保护数据冲突。

关于这个话题,我想知道两件事:

(1) 中断发生在哪里?它们是否保证发生在一个核心上而不是另一个核心上,这是否可以用来确保一个核心上的实时操作不会被另一个核心上可以处理的文件 IO 中断?(我从逻辑上假设中断会发生在第一个核心上,但这总是正确的,你怎么知道?或者也许每个核心都有自己的中断设置?这不会导致每个核心都发生中断吗?核心可以同时对同一个中断做出反应,可能以不同的方式?)

(2) 双核处理器如何处理操作码内存冲突?如果一个核心正在读取内存中的地址,而另一个核心正在写入内存中的同一地址,会发生什么?是抛出异常,还是读取了值?(我假设写入会以任何一种方式工作。)如果读取了一个值,是否保证它是碰撞时的旧值或新值?

我知道理想情况下应该编写程序以避免这些并发症,但操作系统当然不能指望这一点,并且需要能够处理此类事件而不会自己窒息。

4

3 回答 3

7

在 x86 处理器中,这是由 APIC 处理的。您可以在英特尔® 64 和 IA-32 架构软件开发人员手册中查看详细信息,特别是在第 3 卷第 9章和 x2APIC 规范中。

如果您不想深入了解所有细节,我将简要介绍一下。

中断可以来自三个不同的来源:

  • 外部引脚(在高达 Core i7 的 Intel 处理器中,您有 LINT0、LINT1、SMI、INIT。我不知道它们在 Core i7 或 AMD 或 Via 处理器中的名称)。
  • 总线事务。这是现代系统中一个线程向另一个线程发送中断的主要方式。它们被称为IPI -处理器间中断
  • 内部事件,例如热中断、事件监视器或内部错误。

每个逻辑处理器(SMT 系统中的线程、非 SMT 多核系统中的内核、非 SMT 非多核系统中的处理器)都有一个 APIC。APIC 控制逻辑处理器如何响应任何此类中断。

简而言之:

SMI 和 INIT 引脚始终分别连接到 SMI 或 INIT。

如果 APIC 被禁用,LINT0 被路由到 INTR,LINT1 被路由到 NMI,并且 IPI 被忽略。

如果启用:

  • LINT0 、 LINT1 、热事件、事件监视器和错误在LVT (逻辑向量表)中都有一个条目,指定它是否被屏蔽,如果没有,它将是什么类型的中断。
  • 处理 IPI。IPI 包括中断类型(即 INTR、SMI、NMI、INIT、SIPI)和目的地。每个逻辑处理器都有一个 APIC-ID,即 . 如果 IPI 的目标与其 ID 匹配,则它处理中断。否则它会忽略它。

如果您想了解有关启用 APIC、LVT 编程、设置 APIC-ID 和发送 IPI 的详细信息,您必须查看我链接到的手册。

于 2009-05-22T18:33:44.267 回答
2

操作系统开始设置处理中断的位置。Linux 对中断进行负载平衡,以便它们可以由两个 CPU 处理。每个中断处理程序都需要获取一个锁,以避免在不同的 CPU 上同时执行相同的处理程序,还可以防止其他内核代码在非中断上下文中运行并访问相同的数据结构。但是,我认为可以在给定的 CPU 上绑定给定中断的执行。

关于问题(2):保证与SMP机器给出的保证基本相同,即不抛出异常,结果取决于谁先执行/将值提交到内存/将值提交到共享缓存。无论如何,您都不能依赖读取值 - 事实上,给出的保证远没有您预期的那么强大。

在 Internet 上(在 Google 或 Wikipedia 上)查看什么是数据竞争,并从研究如何在 Java 中正确编写多线程代码开始。学习这让我更容易理解 Linux 内核的并发机制。

或者只是去C/C++ 几乎“官方”的内存模型常见问题解答、Linux 内核源代码树中的 Documentation/memory-barriers.txt 或Jeremy Manson 的关于该问题的帖子。无论如何,我忘了指出您读取的值不一定是由某个处理器实际写入的。对于 32 位值,这是由 32 位写入是原子的事实来保证的。对于 64 位值,这通常不是真的(我不确定 64 位平台,但由于可移植性的原因,我通常不依赖它)。

无论如何,如果您发现自己在问这个问题,您可能应该改进代码使用的锁定。在内核中工作,您首先需要编写自己的自旋锁/信号量库来解决这个问题。

当您说“您的内核”时,您的意思并不清楚,但我认为您实际上不太可能是指“我正在编写的内核”。无论如何,我不会让任何人提出问题 (2) 在我的机器上运行多线程程序 :-)。

我知道理想情况下应该编写程序以避免这些并发症,但操作系统当然不能指望这一点,并且需要能够处理此类事件而不会自己窒息。

这个问题的答案是你在编写用户空间多线程程序时需要知道的。好吧,您不需要知道“您读取的值”的确切答案,但仅仅因为您不能依赖它,即使您为特定处理器编写汇编代码,它也是实现定义的。仅仅因为您不能依赖两个并行线程的相对速度。曾经。

于 2009-01-12T10:19:16.390 回答
1

IA-32 参考手册将明确回答您的问题。

我的直觉是两个内核 rx 都会中断,操作系统会对其进行排序。每个内核上可能都有一个设置寄存器,用于指定哪个内核获得哪个中断。

碰撞。没有保证。更准确地说,研究缓存机制以及它们如何解决一致性问题。

对于与此相关的其他线程:

多核/多 CPU 机器中的中断如何工作?

于 2009-01-07T08:10:47.483 回答