首页 > 解决方案 > 大量线程消耗对 ARM(4 核 A72)与 x86(2 核 i5)的影响

问题描述

我有一个实时 linux 桌面应用程序(用 C 编写),我们正在移植到 ARM(4 核 Cortex v8-A72 CPU)。在架构上,它结合了高优先级显式 pthread(其中 6 个)和一对 GCD(libdispatch)工作队列(一个并发和另一个串行)。

我的担忧来自两个方面:

标签: parallel-processingoperating-systemarmmultiprocessinggrand-central-dispatch

解决方案


我不是任何与 x86 架构相关的专家(因此希望更有经验的人可以加入),但这里有一些对您的问题的高级回答。

我听说 ARM 不像 x86 那样超线程 [...]

正确,超线程是英特尔专有的芯片设计功能。我知道没有类似的 ARM 硅技术。

[...],因此我的 4 核已经在进行上下文切换,以跟上我的 6 个 pthread(和后台进程)。我应该期待什么样的性能损失?[...]

情况不一定如此,尽管它很可能在许多情况下发生。这实际上更多地取决于您的每个线程计算的性质......您是在做大量的计算,还是在做大量的阻塞/等待 IO?无论哪种方式,这两种架构都会发生这种退化,并且它更像是一个一般的线程调度问题。在超线程英特尔世界中,操作系统将每个“物理核心”视为两个“逻辑核心”,它们共享相同的资源,但拥有自己的管道和寄存器集。维基百科文章指出:

每个逻辑处理器可以单独停止、中断或指示执行指定线程,独立于共享相同物理内核的其他逻辑处理器。 [7]

与使用两个独立物理处理器的传统双处理器配置不同,超线程内核中的逻辑处理器共享执行资源。这些资源包括执行引擎、缓存和系统总线接口;资源共享允许两个逻辑处理器更有效地相互工作,并允许逻辑处理器从停滞的逻辑核心借用资源(假设两个逻辑核心都与同一个物理核心相关联)。处理器在等待它发送的数据时会停止,以便它可以完成对当前线程的处理。使用超线程或多核处理器时看到的好处程度取决于软件的需求,以及它和操作系统的编写程度以有效地管理处理器。 [7]

因此,如果您的一些线程在 I/O 上不断阻塞,那么这可能是您在 4 个物理核心系统(对于 ARM 和 intel x86)上的 6 线程应用程序中看到更多改进的地方,因为理论上这是超线程的地方会发光....在 IO 或另一个线程的结果上阻塞的线程可以“休眠”,同时仍然允许在同一内核上运行的另一个线程在没有线程切换的全部开销的情况下工作(专家请插话和告诉我我是否在这里错了)。

但是 4 核 ARM 与 2 核 x86 ......假设所有其他条件相同(显然情况并非如此,实际上时钟速度、缓存层次结构等都会产生巨大影响),那么我认为这真的取决于线程。我想如果你只是在做大量纯 cpu 绑定的计算(即线程永远不需要等待 CPU 外部的任何东西),这种性能下降可能会发生。但是,如果您在每个线程中执行大量阻塞 I/O,您可能会显示出显着的加速,每个逻辑核心最多可能有 3 或 4 个线程。

要记住的另一件事是缓存。当进行大量 cpu-bound 计算时,线程切换可能会炸毁缓存,导致最初的内存访问速度慢得多。这将在两种架构中发生。但是,I/O 内存并非如此。但是,如果你没有做很多阻塞的事情,那么由于上述原因,线程的额外开销只会让它变慢。

我听说我应该期望这些 ARM 上下文切换的效率低于 x86。真的吗?

硬件上下文切换是硬件上下文切换,您将所有寄存器推入堆栈并翻转一些位以更改执行状态。所以不,我不相信在这方面两者都“更快”。但是,对于单个物理内核,像超线程这样的技术在操作系统意义上使“上下文切换”(我认为您的意思是在线程之间切换)更快,因为两个程序的指令已经在同一个内核上并行执行.

我对 GCD 一无所知,因此无法对此发表评论。

归根结底,我想说最好的办法是在两种架构上对应用程序进行基准测试。看看你的瓶颈在哪里。它在内存访问中吗?因此,保持高速缓存热是一个优先事项。我想每个核心 1 个线程对于任何情况都是最佳的,如果你可以摆动它的话。

关于这个问题的一些好东西:

  1. https://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html
  2. https://lwn.net/Articles/250967/
  3. 每个核心的最佳线程数
  4. 线程上下文切换 Vs。进程上下文切换

推荐阅读