简单数组处理循环的 AVX 512 与 AVX2 性能对比

2023-12-11

我目前正在研究一些优化并比较 DSP 应用程序的矢量化可能性,这对于 AVX512 来说似乎是理想的选择,因为这些只是简单的不相关数组处理循环。但在新的 i9 上,与 AVX2 相比,使用 AVX512 时我没有测量到任何合理的改进。有什么指点吗?有什么好的结果吗? (顺便说一句。我尝试了MSVC/CLANG/ICL,没有明显的区别,很多时候AVX512代码实际上看起来更慢)


这看起来太宽泛了,但实际上有一些微架构细节值得一提。

请注意,AVX512-VL(矢量长度)允许您使用新的 AVX512 指令(如打包uint64_tdouble128 和 256 位向量上的转换、掩码寄存器等)。现代编译器在针对 Skylake-AVX512(又名 Skylake-X)进行调整时通常会使用 256 位向量进行自动向量化。例如gcc -march=native or gcc -march=skylake-avx512,除非您覆盖调整选项以将首选向量宽度设置为 512,以便进行权衡的代码。请参阅@zam 的回答。


512 位向量的一些主要内容(不是 256 位的 AVX512 指令,例如vpxord ymm30, ymm29, ymm10)在 Skylake-X 上是:

  • 将数据与向量宽度对齐比 AVX2 更重要(每个未对齐的负载都会跨越缓存行边界,而不是在数组上循环时每隔一个)。在实践中,它会产生更大的差异。我完全忘记了我不久前测试过的具体结果,但可能有 20% 的速度减慢,而错位导致的速度减慢不到 5%。

  • 运行 512 位微指令会关闭端口 1 上的矢量 ALU。(但不会关闭端口 1 上的整数执行单元)。某些 Skylake-X CPU(例如 Xeon Bronze)每个时钟只有 1 个 512 位 FMA 吞吐量,但 i7 / i9 Skylake-X CPU 和更高端的 Xeon 在端口 5 上有一个额外的 512 位 FMA 单元,可为AVX512“模式”。

    因此,请相应地进行计划:从扩展到 AVX512,您不会获得双倍的速度,并且代码中的瓶颈现在可能位于后端。

  • 运行 512 位微指令还会限制最大 Turbo,因此挂钟加速可能低于核心时钟周期加速。 Turbo 缩减有两个级​​别:任何 512 位操作,然后heavy512 位,如持续的 FMA。

  • FP除法执行单元为vsqrtps/pd zmm and vdivps/pd is not全屏宽度;它只有 128 位宽,因此 div/sqrt 与乘法吞吐量的比率大约差了 2 倍。参见浮点除法与浮点乘法。 SKX 吞吐量为vsqrtps xmm/ymm/zmm每 3/6/12 个周期 1 次。double-精度是相同的比率,但吞吐量和延迟更差。

    对于 256 位 YMM 向量,延迟与 XMM 相同(sqrt 为 12 个周期),但对于 512 位 ZMM,延迟高达 20 个周期,并且需要 3 uops。 (https://agner.org/optimize/用于指令表。)

    如果您在除法器上遇到瓶颈并且无法在混合中获得更多其他指令,VRSQRT14PS即使您需要牛顿迭代才能获得足够的精度,也值得考虑。但请注意 AVX512 的近似值1/sqrt(x)确实比 AVX/SSE 有更多的保证精度位。)


就自动向量化而言,如果需要任何洗牌,编译器可能会在使用更宽的向量时做得更差。对于简单的纯垂直内容,编译器可以使用 AVX512。

你之前的问题有一个sin函数,也许如果编译器/SIMD 数学库只有 256 位版本,它就不会使用 AVX512 自动矢量化。

如果 AVX512 没有帮助,可能您遇到了内存带宽瓶颈。使用性能计数器进行分析并找出答案。或者尝试多次重复较小的缓冲区大小,看看当缓存中的数据很热时,速度是否会显着提高。如果是这样,请尝试缓存阻止您的代码,或者通过对数据进行一次更多操作来增加计算强度。

AVX512 在 i9 上实现了理论最大 FMA 吞吐量的两倍(以及整数乘法,以及在同一执行单元上运行的许多其他功能),使 DRAM 和执行单元之间的不匹配增加了一倍。因此,更好地利用 L2 / L1d 缓存可以获得两倍的收益。

在数据已经加载到寄存器中时处理数据是很好的。

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

简单数组处理循环的 AVX 512 与 AVX2 性能对比 的相关文章

  • 优化 LATERAL join 中的慢速聚合

    在我的 PostgreSQL 9 6 2 数据库中 我有一个查询 该查询根据一些股票数据构建计算字段表 它为表中的每一行计算 1 到 10 年的移动平均窗口 并将其用于周期性调整 具体来说 CAPE CAPB CAPC CAPS 和 CAP
  • 在 x86 程序集中存储大量布尔值的最佳方法是什么?

    最近我一直在处理充满布尔值的大型数组 目前 我将它们存储在 bss部分有一个 space指令 它允许我创建字节数组 但是 由于我只需要存储布尔值 因此我希望从数组中逐位读取和写入数据 目前 我能想到的最好方法是有一个 space指令所需存储
  • .pdbs 会减慢发布应用程序的速度吗?

    如果 dll 中包含 pdb 程序调试 文件 则行号将出现在引发的任何异常的堆栈跟踪中 这会影响应用程序的性能吗 这个问题与发布与调试 即优化 无关 这是关于拥有 pdb 文件的性能影响 每次抛出异常时都会读取 pdb 文件吗 加载程序集时
  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 使用 g++ 5.3.1 编译的程序运行速度比使用 g++ 4.8.4 编译的相同程序慢 3 倍,相同的命令

    最近 我开始使用 Ubuntu 16 04 和 g 5 3 1 并检查我的程序是否运行慢3倍 在此之前我使用过 Ubuntu 14 04 g 4 8 4 我用相同的命令构建它 CFLAGS std c 11 Wall O3 我的程序包含循环
  • R、Rcpp 与 Armadillo 中矩阵 rowSums() 与 colSums() 的效率

    背景 来自 R 编程 我正在扩展到 C C 形式的编译代码Rcpp 作为循环交换 以及一般的 C C 效果的实践练习 我实现了 R 的等效项rowSums and colSums 矩阵的函数Rcpp 我知道它们以 Rcpp 糖的形式存在 并
  • 为什么n++执行速度比n=n+1快?

    在C语言中 为什么n 执行速度快于n n 1 int n n int n n n 1 我们的老师在今天的课堂上问了这个问题 这不是家庭作业 如果您正在开发一个 石器时代 编译器 的情况下 石器时代 n比n 比n n 1 机器通常有incre
  • 独立滚动矩阵的行

    我有一个矩阵 准确地说 是 2d numpy ndarray A np array 4 0 0 1 2 3 0 0 5 我想滚动每一行A根据另一个数组中的滚动值独立地 r np array 2 0 1 也就是说 我想这样做 print np
  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • NHibernate - CreateCriteria 与 CreateAlias

    假设以下场景 class Project public Job Job class Job public Name 假设我想使用 Criteria API 搜索其 Job 名称为 sumthing 的所有项目 我可以使用 CreateAli
  • 为什么列表理解在数组相乘方面比 numpy 快得多?

    最近我回答了THIS https stackoverflow com questions 31596979 multiplication between 2 lists 31597029 31597029想要两个列表相乘的问题 一些用户建议
  • 为什么X86中没有NAND、NOR和XNOR指令?

    它们是您可以在计算机上执行的最简单的 指令 之一 它们是我亲自实施的第一个指令 执行 NOT AND x y 会使执行时间和依赖链长度和代码大小加倍 BMI1 引入了 andnot 这是一个有意义的补充 是一个独特的操作 为什么不是这个问题
  • 如何提高包含大量小图像的 UCollectionView 的性能?

    在我的 iOS 应用程序中我有UICollectionView显示大约 1200 个小 35x35 点 图像 图像存储在应用程序包中 我正确地重用了UICollectionViewCell但仍然存在性能问题 具体取决于我处理图像加载的方式
  • Swift 使用哪种通用排序算法?它在排序数据上表现不佳

    我一直在挑选和探索 Swift 标准库sort 其函数为Array类型 令我惊讶的是 我注意到它在已经排序的数据上表现不佳 对数组进行排序Int打乱顺序似乎比对已经排序的同一个数组进行排序快 5 倍 对已打乱顺序的对象数组进行排序比对已按排
  • 针对约 225 万行的单表选择查询的优化技术?

    我有一个在 InnoDB 引擎上运行的 MySQL 表 名为squares大约有 2 250 000 行 表结构如下 squares square id int 7 unsigned NOT NULL ref coord lat doubl
  • 为什么改变对象的 [[prototype]] 会降低性能?

    来自 MDN 文档standard setPrototypeOf功能 https developer mozilla org en US docs Web JavaScript Reference Global Objects Object

随机推荐

  • 有没有 ios-ntp 的替代方案来获取原子/当前时间 ios?

    在我的应用程序中 我想获得准确的日期和时间 基本上 在我的应用程序中 会有一个时间敏感部分 用户只有在特定时间之后才能启动 但是 如果我从设备中获取日期和时间 用户可以轻松更改设备上的日期和时间 Settings gt General gt
  • 在 jar 中加载文件

    我需要将配置文件打包到 jar 中 配置文件位于 jar 文件的根目录下 但是我收到以下错误 引起原因 java lang IllegalArgumentException URI 不是分层的 在 java io File 来源未知 Fil
  • python:将 1/0 列表转换为布尔值列表

    尝试将 1 0 列表转换为布尔值列表 bool 1 0 1 0 似乎不起作用 1 0 1 0 1不起作用 还有另一种方法 希望是非列表理解 吗 在Python 2中 bool list map bool int list 在Python 3
  • 从 XPath 表达式填充 XML 模板文件?

    从 XPath 表达式的映射填充 或生成 XML 模板文件的最佳方法是什么 要求是我们需要从模板开始 因为这可能包含 XPath 表达式中未捕获的信息 例如 起始模板可能是
  • 在c中不使用线程和sleep()方法定期调用函数

    我想调用一个函数 假设每 10 或 20 秒调用一次 当我搜索时 我想出了一些线索sleep 方法无处不在 我还检查了 C 中的时间和时钟类 但找不到任何对我的问题有帮助的内容 定期调用函数的最简单方法是什么 Use libevent在我看
  • 来自 Windows 窗体应用程序的 HTTP Post C#

    我需要用 C 编写一个表单应用程序 通过 HTTP POST 将参数发送到 url 并返回响应 我真的不知道从哪里开始 这可能吗 预先感谢 加尔 首先请参阅 1 HttpWebRequest类 2 HttpWebResponse类 3 We
  • 如何使谷歌表格公式只计算一次?

    我的 Google 表格中有 3 行 即股票 价格和总计 所以 我只是对股票和价格使用 多个 公式 然后将值放入总行中 但我不希望每当我更改库存值时总行都会更新或更改值 有人能帮我吗 假设您希望单元格 A1 只计算一次其值 您可以将以下内容
  • 在 ASP.NET MVC 中跟踪 LINQ TO SQL 生成的查询

    关于 LINQ to SQL 生成的查询输出的快速问题 我正在使用 ASP NET MVC 项目 Visual Studio 2008 并且正在尝试 MSDN 文档中的建议 MyDataContext dc new MyDataContex
  • MOQ- 使用 Func 参数设置和验证通用方法

    我有一个第三方接口 我想模拟它的方法 为了明确我的目的 请考虑以下 IFoo 接口 它具有像 M2 这样的通用方法 M2 参数之一的类型为 Func public interface IFoo bool M1
  • 从 HandlerInterceptor 抛出 HTTP 状态代码异常

    我正在尝试创建一个 HandlerInterceptor 其预处理的代码结构如下 public boolean preHandle HttpServletRequest req HttpServletResponse res Object
  • 如何删除基于另一个 DataFrame 的列上的 DataFrame 中的行?

    我正在尝试使用SQLContext subtract 在 Spark 1 6 1 中 根据另一个数据帧中的列从数据帧中删除行 让我们举个例子 from pyspark sql import Row df1 sqlContext create
  • FAB 的片段布局与 CoordinatorLayout 冲突

    我在用着材料抽屉 with a MainDrawerActivity我替换里面的每个片段容器 FrameLayout基于所选项目 但我想添加一个与以下项交互的 FAB 仅针对此片段 CoordinatorLayout所以它可以处理很酷的动画
  • 将小数转换为分数

    我正在尝试将十进制数转换为其分数 小数点后最多有 4 位数字 示例 12 34 1234 100 12 3456 123456 10000 我的代码 include
  • 弃用 FBML

    您可能已经知道 或阅读本文末尾的引用 Facebook 正在弃用 FBML 转而使用 iframe 来开发应用程序 我目前正在启动一个新的浏览器插件 需要在我的 Facebook 页面上有一个登陆选项卡 其中包含个性化安装按钮以及人们希望在
  • 为什么我不能使用两个 i32 参数调用 gen_range?

    我有这段代码 但它无法编译 use rand Rng use std io fn main println Guess the number let secret number rand thread rng gen range 0 101
  • 在 Ajax 中处理非常大的长数字的最佳方法?

    Javascript 将所有数字表示为双精度浮点数 这意味着在处理 64 位 Java Long 数据类型最高端的数字 17 位数字之后的任何数字 时 它会失去精度 例如 数字 714341252076979033 变为 714341252
  • For 循环迭代字符串切片不起作用

    我编写了这段代码 它将小写英语短语翻译成猪拉丁语 package main import fmt strings bufio github com stretchr stew slice regexp os func main lst st
  • Qt:当主窗口被模式 QDialog 阻塞时,如何将焦点集中到从主窗口创建的无模式 QDialog

    在我的 Qt 应用程序中 我面临以下场景 当引发特定事件时 我会显示无模式QDialog要求用户确认 对话框显示使用show 函数从一个QMainWindow 任何时候引发事件并且没有其他模式QDialog显示后 用户可以单击确认按钮 不幸
  • 后台信标监控的响应能力(Android Beacon Library / Kontakt SDK / Estimote SDK)

    背景 我正在开发一个 Android 应用程序 用于监视后台的特定信标 并在检测到进入时执行自定义编码 我目前正在使用 Android Beacon Library 进行探索 并且能够在屏幕打开时 几秒钟内 的大部分时间响应地检测到信标 但
  • 简单数组处理循环的 AVX 512 与 AVX2 性能对比

    Closed 这个问题需要调试细节 目前不接受答案 我目前正在研究一些优化并比较 DSP 应用程序的矢量化可能性 这对于 AVX512 来说似乎是理想的选择 因为这些只是简单的不相关数组处理循环 但在新的 i9 上 与 AVX2 相比 使用