c - 流式 Simd 扩展 (SSE) 的按位运算
问题描述
我想了解在以下 C 中的最小示例中使用 Streaming Simd Extensions (SSE) 进行整数之间的按位运算的潜在收益。
假设一个
- 在两个 64 位 unsigned long long int
a
和b
(1) 之间进行按位运算,例如,a ^ b
- 在两个 128 位整数
A
和B
SSE 之间进行相同的按位运算。
我想知道执行(1)是否与(2)花费相同的时间。
例如,可以尝试进行计时实验,其中测量进行 N >> 1 位操作 (1) 的时间和进行相同数量的操作 (2) 的时间。
这些时间大致相同吗?如果不是,那么它们在特定机器上的比例是多少?对于 256 或更大的 SSE 扩展,同样的问题如何?
解决方案
您是在谈论作为已编译 C 函数的一部分吗?编译器可以轻松地使用 AVX2vpxor
或 AVX1对数组上的循环进行自动矢量化vxorps
,因此^
运算符的编译方式取决于周围的上下文。
显然,您必须在启用优化的情况下进行编译,才能使任何基准测试有意义。
至于硬件在 asm 级别上可以做什么,编译器生成或手写并不重要。使用内在函数是让编译器发出 SIMD 指令的便捷方式。
我们以 Intel Haswell 为例。没有内存瓶颈,只需对寄存器中的局部变量进行操作,使用 AVX2,您可以获得vpxor ymm
每个时钟 3 倍(加上另一个非 SIMD uop),因此这是 3 倍 256 位的 XOR。(在 Intel CPU 上,128 位 SSE2pxor xmm
与 256 位 AVX2 具有相同的吞吐量vpxor
,因此更宽的向量纯粹是吞吐量的胜利)。
xor
或者使用纯标量代码,如果您没有其他指令,您可以在 Haswell 上执行 4x 标量 8/16/32/64 位/时钟。
两者都是单 uop,具有 1 个周期延迟vpxor
。xor
在 AMD Bulldozer 系列和更早的版本上,pxor
/vpxor
有 2 个周期延迟,但每个时钟吞吐量有 2 个,因此延迟瓶颈与吞吐量瓶颈之间的性能差异是 4 倍。
如此小规模的 CPU 性能不是一维的。 超标量流水线无序 CPU 使您提出的“是否需要更长的时间”的问题过于简单化。请参阅我关于预测现代超标量处理器上的操作延迟的考虑因素以及如何手动计算它们的答案?,特别是“短块分析的三个主要维度”部分。
请参阅https://agner.org/optimize/和x86 标签 wiki中的其他性能链接。
推荐阅读
- python - 从 pyinstaller 获取独立的 exe 文件
- spring-boot - Spring使用保存更新所有实体
- java - 如何解决这个整数数组排序不能按预期工作?
- asp.net - 尝试使用 OleDbCommand 将常规或类型的 excel 行与字符串进行比较时出现数据类型不匹配异常
- javascript - 如何在“new Promise”块中使用 async/await 从 api 获取数据?
- sql - 我想在两个具有数组数据的表之间建立关系(postgresql)
- python - 从多索引到多列
- camera - 相机的外在矩阵
- d3.js - d3缩放平移到折线图的特定区域
- android - android.view.WindowLeaked / Android Intent