SIMD 需要多核 CPU 吗?

2023-12-20

实现SIMD是否需要多核CPU?

在阅读有关 SIMD 的维基百科时,我发现了以下短语“多个处理元素”。那么这句话和“多核CPU”有什么区别呢?


每个核心都有自己独立的SIMD执行单元。在一个内核中使用 SIMD 指令不会消耗其他内核中的执行资源。即使在同一物理芯片上的单独内核也是独立的,因此它们可以单独进入睡眠状态以节省电量,以及保持它们隔离的各种其他设计原因。

我知道的一个例外是:AMD Bulldozer 有两个弱整数核心,共享一个 SIMD/FPU 并共享一些缓存。他们称之为“集群”,它基本上是超线程 (SMT) 的替代方案。看大卫·坎特 (David Kanter) 在 RealworldTech 上的推土机文章 https://www.realworldtech.com/bulldozer/.

SIMD 和多核是正交的:您可以拥有多核而无需 SIMD(可能某些 ARM 芯片没有 FPU/NEON),也可以拥有 SIMD 而无需多核。

后者的许多例子,包括最著名的早期 x86 芯片,如 Pentium-MMX 到 Pentium III / Pentium 4,它们具有 MMX / SSE1 / SSE2,但都是单核 CPU。


程序中至少存在三种不同类型的并行性:

  • 指令级并行性 https://en.wikipedia.org/wiki/Instruction-level_parallelism:可以在同一个执行线程中重叠不同指令完成的一些工作,从而保留逐条运行每条指令的错觉。通过构建流水线 CPU 核心或超标量(每个时钟多条指令),甚至乱序执行来利用它。 (看我对此问题的回答 https://softwareengineering.stackexchange.com/questions/349972/how-does-a-single-thread-run-on-multiple-cores/350024#350024了解详情。)

    创建软件时:通过尽可能避免长依赖链来向硬件公开这种并行性。 (例如替换sum += a[i++] with sum1+=a[i]; sum2+=a[i+1]; i+=2;:使用多个累加器展开)。或者使用数组而不是链表,因为要加载的下一个地址的计算成本很低,而不是成为内存中数据的一部分,您必须等待缓存未命中。但大多数 ILP 已经存在于“正常”代码中,无需执行任何特殊操作,并且您可以构建更大/更高级的硬件来找到更多它,并增加每个时钟的平均指令数。

  • 数据并行性 https://en.wikipedia.org/wiki/Data_parallelism: 你需要做的same图像的每个像素或音频文件中的每个样本。 (例如混合 2 个图像,或混合两个音频流)。通过在每个 CPU 核心中构建并行执行单元来利用这一点因此,一条指令可以并行执行 16 个单字节加法,从而提高吞吐量,而无需增加每个时钟通过 CPU 内核所需的指令量。这是SIMD:单指令,多数据。

    音频/视频是最著名的应用,其中加速是massive因为您可以将大量字节或 16 位元素放入单个固定宽度向量寄存器中。

    通过使用智能编译器自动向量化循环来利用 SIMD,或手动。 SIMD 转数sum += a[i]; into sum[0..3] += a[i+0..3](对于每个向量 4 个元素,例如int or float与 32 位向量)。

  • 线程/任务级并行性 https://en.wikipedia.org/wiki/Task_parallelism:利用多核CPU,通过手动编写多线程代码暴露给硬件,或者使用OpenMP或其他自动并行化工具对循环进行多线程处理,或者使用启动多个线程进行大矩阵乘法的库函数或者其他的东西。

    或者更简单地通过一次运行多个单独的程序。例如编译用make -j8使 8 个编译进程同时运行。还可以通过在多台计算机集群甚至分布式计算上运行工作负载来利用粗粒度任务级并行性。

    但是,多核 CPU 使得利用细粒度线程级并行性成为可能/高效,其中任务需要共享大量数据(如大型数组),或者通过共享内存进行低延迟通信。 (例如,使用锁来保护共享数据的不同部分,或无锁编程。)

这三种并行性是正交的。

总结一个非常大的数组float在现代 CPU 上:

您将为每个 CPU 核心启动一个线程,并让每个核心循环访问共享内存中的数组块。 (线程级并行性)。比方说,这可以使您的速度提高 4 倍。 (即使由于内存瓶颈,这可能是不现实的,但您可以想象一些其他不需要读取这么多内存的计算密集型任务,在 28 核 Xeon 或具有其中两个芯片的双插槽服务器上运行。 .)

每个线程的代码将使用 SIMD 在每个内核上分别执行每条指令 4 或 8 次加法。 (SIMD)。这将为您带来 4 或 8 倍的加速。 (或 AVX512 为 16)

您可以使用 8 个向量累加器展开来隐藏浮点加法的延迟。 (ILP)。天湖的vaddps指令的延迟为 4 个周期,吞吐量为 0.5 个周期(即每个时钟 2 个周期)。因此,8 个累加器勉强足以隐藏该延迟并同时保持 8 个 FP 添加指令运行。

相对于单线程标量的总吞吐量增益sum += a[i++]是所有这些加速因素的乘积: 4 * 8 * 8= 256x 非并行化、非向量化、单累加器 ILP 瓶颈幼稚实现的吞吐量,就像您从gcc -O2一个简单的循环。clang -O3 -march=native -ffast-math会给出 SIMD 和一些 ILP(因为 clang 知道如何在展开时使用多个累加器,通常使用 4 个累加器,与 gcc 不同。)

您需要 OpenMP 或其他自动并行化来利用多个内核。

有关的:为什么mulss在Haswell上只需要3个周期,与Agner的指令表不同? https://stackoverflow.com/questions/45113527/why-does-mulss-take-only-3-cycles-on-haswell-different-from-agners-instruction更深入地了解 ILP 和 SIMD 的多个累加器以及 FMA 循环。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SIMD 需要多核 CPU 吗? 的相关文章

  • Xcode 9 - CPU 使用率高 - 风扇最大速度

    自从我升级到 Xcode 9 后 当我在 Xcode 上工作时 我的粉丝就变得疯狂了 当我使用 Storyboards 和 Interface Builder 时 尤其会发生这种情况 Xcode有时会占用100 的CPU 并且名为 Inte
  • 进行水平 SSE 向量和(或其他简化)的最快方法

    给定一个由三个 或四个 浮点数组成的向量 对它们求和的最快方法是什么 SSE movaps shuffle add movd 总是比 x87 快吗 SSE3 中的水平相加指令值得吗 转移到 FPU 然后是 faddp faddp 的成本是多
  • MIPS 中的影子寄存器是什么以及它们如何使用?

    当我了解 MIPS 架构时 我遇到了影子寄存器 据说它们是通用寄存器的副本 我无法理解以下内容 何时使用影子寄存器 MIPS 影子寄存器用于减少处理中断时的寄存器加载 存储开销 分配了影子寄存器组的中断不需要保存任何现有上下文来提供空闲寄存
  • 将 CPU 频率指定为 Linux 启动时的内核 CMD_LINE 参数?

    我将笔记本电脑的i5 CPU更换为i7 CPU 这样它可以运行得更快 但由于i7的功率更大 温度也比以前更高 所以我的笔记本经常死机 所以 我使用cpupower来指定CPU的最大频率 它起作用了 现在 我的问题是 有没有办法在启动时将CP
  • C 易失性变量和高速缓存

    缓存是由缓存硬件对处理器透明地控制的 因此如果我们在C程序中使用易失性变量 如何保证我的程序每次都从指定的实际内存地址读取数据而不是缓存 我的理解是 Volatile 关键字告诉编译器不应优化变量引用 而应按照代码中的编程方式读取变量引用
  • Linux:如何对系统内存施加负载?

    我正在开发一个小功能 它可以让我的用户了解 CPU 的占用情况 我在用着cat proc loadavg 它返回众所周知的 3 个数字 我的问题是 当我正在开发时 CPU 目前没有做任何事情 有没有一种好方法可以在CPU上产生一些负载 我在
  • 手臂“版本”之间的差异? (仅限 ARMv7)

    基本上我想知道ARMv7l和ARMv7之间的区别hl 我有一个带有armv7l的arm处理器 并且有很多armv7的rpmhl 我完全不知道我必须搜索什么才能获得相关信息 这个 后缀 叫什么 还有其他类型吗 他们的做法有何不同 我假设它指示
  • 阿迪和苏比之间到底是什么“关系”?

    我应该回答这个问题 经过一番研究后发现 add 和 sub 具有相同的操作码 仅在功能领域有所不同 这是答案还是其他什么 Update Nios II CPU 手册中提供了它 subi subtract immediate Operatio
  • SSE加载和添加

    假设我有两个由两个类型数组表示的向量double 每个尺寸为2 我想添加相应的位置 所以假设向量i0 and i1 我想补充一下i0 0 i1 0 and i0 1 i1 1 一起 由于类型是double 我需要两个寄存器 诀窍是把i0 0
  • 调用always_inline‘_mm_mullo_epi32’时内联失败:目标特定选项不匹配

    我正在尝试使用 cmake 编译 C 程序 该程序使用 SIMD 内在函数 当我尝试编译它时 出现两个错误 usr lib gcc x86 64 linux gnu 5 include smmintrin h 326 1 错误 调用alwa
  • 通过 C 将线程固定到 cpuset 中的核心

    我有 cgroup cpuset set1 set1有2 5 8 我想将一个进程绑定到该 cpuset 然后将该进程中的一个线程固定到核心 4 cpuset 的名称 线程名称以及我应该将线程绑定到的核心位于 m 配置文件中 是否有任何 C
  • CPU缓存:两个地址之间的距离是否需要小于8字节才能具有缓存优势?

    这似乎是一个奇怪的问题 假设缓存行的大小为 64 字节 此外 假设 L1 L2 L3 具有相同的缓存行大小 this https stackoverflow com a 15333156 8385554帖子说英特尔酷睿 i7 就是这种情况
  • 当我打开在 Xcode 4 中创建的 Google 地图项目时,Xcode 5 会警告我的架构设置

    我刚刚更新到新发布的 Xcode 5 我正在开发一个使用 Google 地图 iOS SDK 的 iOS 应用程序 当我在 Xcode 4 中开发时 我改变了我的Architectures在我的项目设置中进行设置 按照 Google 的步骤
  • Verilog 双向握手示例

    我正在完成一个项目 要求是处理器内部功能单元之间的双向握手 我知道它是什么 但是有没有任何 标准 或一个简单的例子 我唯一能想到的就是两个单元之间 当它们之间有一条数据线并且当 X 发送到 Y 时 会给出一个单独的 发送 信号 当 Y 接收
  • CPU是如何做减法的?

    我有一些基本的疑问 但每次我坐下来尝试面试问题时 这些问题和我的疑问就会出现 假设 A 5 B 2 假设A和B都是4字节 那么CPU是怎么做的呢 A B添加 我知道 A 的符号位 MSB 为 0 表示正值 B 的符号位为 1 表示负整数 现
  • 获取总体 CPU 百分比使用率的可能性有哪些

    我有以下问题 在UWP中 我们如何获取总体CPU使用率 RAM使用率 可用RAM 正在运行的进程等 UWP 中的任务管理器需要它 您好 经过一番查看后 您似乎无法获得设备 CPU RAM 和可用 RAM 或正在运行的进程 您可以获得 CPU
  • 是否可以在VM内使用VMX CPU指令?

    VM guest 内部的进程是否有可能使用 VMX AMD V VT x CPU 指令 然后由外部 VMM 处理而不是直接在 CPU 上处理 Edit 假设外部VM使用VMX本身来管理其虚拟客户机 即它在Ring 1中运行 如果可能的话 是
  • SIMD 和 VLIW 指令是一样的吗?

    SIMD 单指令多数据 和 VLIW 超长指令字 到底有什么区别 其中一个是另一个的子集吗 或者它们是两个完全不同的东西 完全不相关且正交 一台机器可以有一个或两个 或者两者都没有 SIMD 指令可以作为扩展添加到 VLIW ISA 但 V
  • 分支预测器和分支目标缓冲区如何共存?

    我的问题是它们如何在现代 CPU 架构中共存并协同工作 你把它稍微颠倒了 每次获取时 您都会索引到分支预测器 它会告诉您刚刚收到的指令是否will be解码为已采取的分支 如果没有 则获取下一个连续地址 但是 如果您的分支预测器说它将是一个
  • Intel:序列化指令和分支预测

    英特尔架构开发人员手册 http www intel com content www us en architecture and technology 64 ia 32 architectures software developer v

随机推荐

  • 使用selenium下载文件

    我正在使用硒来测试系统 我必须下载一个文本文件 为了直接下载它 我创建了一个 Firefox 配置文件 它应该避免Save cancel对话框 但是对话框仍然会出现 我的代码如下 FirefoxProfile fxProfile new F
  • 如何在 Pandas Groupby 中仅显示具有值的列

    我需要一些帮助 因为我无法正确组织数据 这是我的数据框 df dict Date Timestamp 2014 01 03 00 00 00 Store store1 employee emp1 duties opening Date Ti
  • 谷歌搜索中网站下方的链接

    当我在谷歌中搜索亚马逊等网站时 我看到了亚马逊的链接和描述 在主链接下面我还看到一些较小的链接 例如书籍 音乐 DVD 等 我们如何才能获得我们自己网站的这些链接 这些是站点地图吗 那些是 您可以使用 Google 网站管理员工具阻止它们
  • 参数超出范围异常

    Random r new Random int InvadorNumberA r Next 0 5 int randomShot r Next 5 List
  • 如何按顺序播放多个音频文件

    我有几个长篇故事 其源音频是逐句音频文件 我想创建一个网页 人们可以在其中多次聆听特定故事的各个句子 或者从头到尾聆听整个故事 首先 我的网页有很多
  • 当用户未登录时如何将用户重定向到登录页面

    当用户登录时 我们将其用户 ID 存储在会话中 session user id user id 现在 在我们网站的所有其他链接上 我们希望用户重定向 如果session user id nil 我认为完成的方式是在控制器的每个方法中完成 d
  • 强制 git 推送后如何拉取?

    假设我从 git 存储库中提取更改 然后repo的作者强制推送到中央repo 现在我无法拉动 因为历史被重写了 假设作者强制推送了正确的版本 如何提取新的提交 并放弃旧的提交 我知道这是糟糕的 git 工作流程 但有时你无法避免这种情况 丢
  • 如何将文件上传到jenkins并使用它来构建?

    我对 Jenkins 很陌生 我一直在尝试使用curl 来构建我的工作 除了这个卷曲之外 我还想向 Jenkins 发送一个文件 该文件应该放置在我工作区的特定目录中 我一直在谷歌上搜索很多 但似乎找不到可以引导我找到解决方案的明确文档 请
  • 您可以将 JavaScript 和 CSS 文件存储在 localStorage 中以提高在线 Web 应用程序的性能吗?

    我正在开发一个 Web 应用程序 它的行为非常类似于 iOS 和 Android 的本机应用程序 然而 Javascript 文件 jQuery 我自己的 和 css 文件对于移动使用来说相当大 如果用户没有启用 3G 这会使应用程序加载缓
  • IIS 强制斜杠,即使使用 URL 重写来删除它

    即使 URL 重写如下 我也无法删除网站 URL 的尾部斜杠 http ruslany net 2009 04 10 url rewriting tips and tricks http ruslany net 2009 04 10 url
  • Oracle 和 Eclipse 编译器生成的 java 字节码的差异

    我们的项目做了一些 Java 字节码检测 我们偶然发现了一些奇怪的行为 假设有以下代码片段 public void a new Integer 2 Oracle的javac将上面的内容编译成如下字节码 0 new 2 class java
  • 尝试使用 Windows powershell 创建新的 Angular 项目时出现错误:“操作被操作系统拒绝”

    尝试创建新的角度项目时 我不断收到相同的错误消息 我尝试使用 Windows Powershell 使用以下命令创建一个新的角度项目 ng 新的你好世界 gt 您想添加角度路由吗 是的 gt 样式表格式 CSS 我收到以下错误消息 我已经尝
  • 如何在 Apache Tomcat 中初始化 Web 应用程序?

    我使用的是 WebSphere Application Server 它提供了一个平台初始化侦听器 当应用程序启动时会调用该侦听器 现在 我正在使用 Apache Tomcat 但还没有找到这样的东西 我想做的是在应用程序开始服务请求之前做
  • Android:在 onCreate 之前设置活动方向,但不在清单中(HDMI 插入问题)

    我可以通过使用以编程方式完美管理方向变化setRequestedOrientation in onCreate 一切都工作得很好 直到我插入 HDMI 电缆 此后 平板电脑 想要 处于横向模式 因此 当我打开一个活动时 它首先显示为 横向
  • 在 PHP 中使用 cURL 从 URL 读取 XML

    我想从 Magento 中的 URL 读取 XML 数据 我有三个文本框 一个用于baseurl 其他分别用于用户名和密码 当我输入这些值时 我得到的网址如下 http xyz com somefile html 用户名 用户名 密码 密码
  • 接口中的静态方法需要 -target:jvm-1.8

    我正在使用 gradle 4 5 scala 2 11 11 2 12 4 和 JDK 1 8 0 162 构建 scala 项目 它工作正常 直到我升级到 scala 2 11 12 使用 2 11 12 我不断收到编译错误 Static
  • 自定义argparse帮助消息

    我编写了以下示例代码来演示我的问题 import argparse parser argparse ArgumentParser parser add argument v version action version version pr
  • 如何跨页面使用store和session变量?

    当访问一个页面时 我想启动一个会话并存储一个会话变量 然后从另一个页面 我想检查该会话变量是否已存储 这段代码对我不起作用 分步会议 在一
  • 谷歌地图地点自动完成 addEventListener 不起作用

    我一直在尝试在 ionic 2 项目中添加谷歌地图位置自动完成功能来更新用户位置 但是 addEventListener 似乎不起作用 并且没有控制台错误 有人能告诉我哪里出了问题吗 ngAfterViewInit let input lt
  • SIMD 需要多核 CPU 吗?

    实现SIMD是否需要多核CPU 在阅读有关 SIMD 的维基百科时 我发现了以下短语 多个处理元素 那么这句话和 多核CPU 有什么区别呢 每个核心都有自己独立的SIMD执行单元 在一个内核中使用 SIMD 指令不会消耗其他内核中的执行资源