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 吗? 的相关文章

  • 哪种架构称为非均匀内存访问(NUMA)?

    根据wiki http en wikipedia org wiki Non uniform memory access 非均匀内存访问 NUMA 是一种用于多处理的计算机内存设计 其中内存访问时间取决于相对于处理器的内存位置 但尚不清楚它是
  • 优化数组压缩

    假设我有一个数组k 1 2 0 0 5 4 0 我可以按如下方式计算掩码m k gt 0 1 1 0 0 1 1 0 仅使用掩码 m 和以下操作 左移 右移 And Or 加 减 乘 我可以将 k 压缩为以下形式 1 2 5 4 以下是我目
  • C++ 中的 CPUID 实现

    我想知道这里是否有人有一些可以从任何托管 net 语言引用的 C CPUID 实现的好示例 另外 如果情况并非如此 我是否应该注意 X86 和 X64 之间的某些实现差异 我想使用 CPUID 来获取运行我的软件的机器上的信息 崩溃报告等
  • CPU是如何做减法的?

    我有一些基本的疑问 但每次我坐下来尝试面试问题时 这些问题和我的疑问就会出现 假设 A 5 B 2 假设A和B都是4字节 那么CPU是怎么做的呢 A B添加 我知道 A 的符号位 MSB 为 0 表示正值 B 的符号位为 1 表示负整数 现
  • 没有 FPU 的处理器中的浮点计算

    是否可以在没有浮点单元的嵌入式处理器中执行浮点运算 是的 您只需要在软件中完成即可 你的编译器可能会提供支持 http gcc gnu org onlinedocs gccint Soft float library routines ht
  • 为什么如果内存组织为字,则程序计数器加 1;如果内存组织为字节,则程序计数器加 2?

    如果在计算机中一条指令是 16 位 并且如果存储器被组织为 16 位字 则通过在当前指令的地址中加 1 来计算下一条指令的地址 如果内存是按字节组织的 可以单独寻址 那么我们需要在当前指令地址上加二 得到顺序执行的下一条指令的地址 为什么会
  • 大数组上的 SSE 性能较慢

    我是 SSE 编程新手 所以我希望有人可以帮助我 我最近使用 GCC SSE 内在函数实现了一个函数来计算 32 位整数数组的总和 下面给出了我的实现代码 int ssum const int d unsigned int len stat
  • NodeJS CPU 一次飙升至 100%

    我有一个用 NodeJS 编写的 SOCKS5 代理服务器 我正在使用原生net and dgram打开 TCP 和 UDP 套接字的库 它可以正常工作大约 2 天 所有 CPU 的最大利用率约为 30 两天没有重新启动后 一个 CPU 峰
  • CPU 周期与总 CPU 时间

    在 Windows 上 GetProcessTimes 和 QueryProcessCycleTime 可用于获取应用程序所有线程的总计 我期望 显然是天真地 找到总周期数和总处理器时间 用户 内核 之间的比例关系 当转换为相同的单位 秒
  • PHP 脚本不断执行 mmap/munmap

    我的 PHP 脚本包含一个循环 它只不过是回显和取消引用指针 如 tab othertab i gt 中的内容 直到昨天 这个脚本开始变得非常慢 比以前慢了 50 倍 之前 它一直运行良好 使用 strace 后 我发现 90 的情况下 脚
  • 标志寄存器中保留/未定义位的用途是什么?

    在 Z80 8080 8085 和 8086 处理器的标志寄存器中 被记录为 保留 或 未定义 的位 1 3 5 的用途是什么 这些位未使用 也就是说 没有指令明确地将它们设置为任何值 设计人员认为 5 6 个标志就足够了 他们只是将标志寄
  • 如何在 Java 中将帧速率限制为 60 fps?

    我正在编写一个简单的游戏 我希望将帧速率限制在 60 fps 而不会让循环占用我的 CPU 我该怎么做 您可以阅读游戏循环文章 https dewitters com dewitters gameloop 在尝试实现任何内容之前 首先了解游
  • 除了 gcc 之外,还有哪些编译器可以对代码进行向量化?

    GCC can 矢量化循环 ftp gcc gnu org pub gcc summit 2004 Autovectorization pdf当指定某些选项并给出正确的条件时 会自动进行 是否还有其他广泛可用的编译器可以执行相同的操作 IC
  • 如何在 AVX/AVX2 中递增向量

    我想使用内在函数来增加 SIMD 向量的元素 最简单的方法似乎是为每个元素加 1 如下所示 note vec inc之前已设置为1 vec mm256 add epi16 vec vec inc 但是是否有任何特殊指令来增加向量 类似于in
  • A64 Neon SIMD - 256 位比较

    我想将两个小端 256 位值与 A64 Neon 指令 asm 进行有效比较 平等 为了平等 我已经有了解决方案 bool eq256 const UInt256 lhs const UInt256 rhs bool result 首先 将
  • Python:获取Windows操作系统版本和架构

    首先 我不认为这个问题是重复的 在Python中检测64位操作系统 windows https stackoverflow com questions 2208828 detect 64bit os windows in python因为恕
  • 如何将位对从 uint64_t 解压缩到 __m256i?

    考虑uint64 t其中每连续 2 位都是一个数字 b00 for 0 b01 for 1 b11 for 1 and b10未使用 永远不会发生 假设没有对其进行处理 如何解压这样的uint64 t into m256i以便原始数字中的位
  • (Nand2tetris CPU)每个时钟周期发生(什么/多少)?

    在此基础上Nand2俄罗斯方块 https www coursera org learn build a computer lecture gjhcz unit 5 5 project 5 overviewCPU 如下图 我想了解一下 每个
  • 在硬件不足的情况下进行编码

    我目前正在使用 C 中的 SIMD 指令进行编码 并尝试使用 IDE 在实时编码时显示错误 拼写错误等 问题是 我使用的是 AVX512 指令 我的硬件不支持这些指令 只有我用于编译的服务器支持 有没有一种方法可以在 IDE 中进行错误检查
  • 与 SSE 比较 16 字节字符串

    我有 16 字节的 字符串 它们可能更短 但您可能会假设它们在末尾用零填充 但您可能不会假设它们是 16 字节对齐的 至少不总是 如何编写一个例程将它们与 SSE 内在函数进行比较 是否相等 我发现这个代码片段可能会有帮助 但我不确定它是否

随机推荐

  • 使用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 指令不会消耗其他内核中的执行资源