问题标签 [fma]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
performance - X86 Broadwell 上的吞吐量 FMA 和乘法
我怀疑最后一个英特尔架构会MUL
像 a 一样执行助记符,FMA
但添加了一个空值(在 broadWell 架构上)。
具体来说,我目前正在按照模式执行二次多项式 (Pi) 的乘积。
每个多项式 Pi(x) = a + bX +cX^2 由两个连续的计算FMA
。但是,当我测量问题的吞吐量时,数字非常低。根据 Agner Fog 表Agner FogFMA
第 242 页,a和的吞吐量MUL
为 0.5。吞吐量的定义:是[周期]中执行一个新的相同助记符的时间。
FMA
所以我应该在和之间得到一个惩罚MUL
,但是我的测量是平滑的。我怀疑引擎盖下的处理器将MUL
aFMA
与空加法交换,或者至少使用 FPU 中电路的相同部分,这解释了我的结果。
我可能完全错了,但如果硬件工程师可以确认或确认。
c++ - 了解 FMA 性能
我想了解如何计算 FMA 性能。如果我们查看这里的描述:
对于 Skylake 架构,指令具有Latency=4
和Throughput(CPI)=0.5
,因此指令的整体性能是4*0.5 = 2
每条指令的时钟数。
据我所知,如果最大(涡轮)时钟频率为 3GHz,那么对于单个内核,我可以在一秒钟内执行 1 500 000 000 条指令。
这样对吗?如果是这样,我观察到性能略高的原因可能是什么?
floating-point - clang/gcc 仅使用 -ffast-math 生成 fma;为什么?
在 icc 19 上,点积编译为 fma 指令上的循环。在 clang 和 gcc 上,fma 仅使用-ffast-math
.
但是,-ffast-math
违反了 IEEE 合规性,但 fma 完全符合 IEEE-754 2008,所以如果我必须使用 编译-ffast-math
,那么我会导致其他问题。
为什么 gcc 和 clang 不生成 fma 指令-ffast-math
?
神螺栓;编译器标志是-O3 -march=skylake-avx512
, +- -ffast-math
。
c++ - 浮点计算能否用于任何可靠的功能,尤其是容器和算法?
在 C 和 C++ 中,浮点计算在默认情况下是不确定的,因为用户甚至没有选择真正的数据类型,对于 FP 子表达式的任何中间计算,编译器可以选择以更高的精度表示一个值(即作为另一个真正的数据类型)。
[众所周知,一些编译器 (GCC) 会对任何自动变量执行此操作,而不仅仅是子表达式的(匿名)中间结果。]
编译器可以在某些函数中进行一些计算;它在某些情况下可以做到这一点,而对于完全相同的子表达式则不能。
它甚至可以内联一个函数,并在源代码中每次调用函数时使用不同的精度。这意味着任何可内联函数都可以有其语义调用依赖;只有单独编译,ABI 调用函数(根据 ABI 描述的约定调用并且本质上充当黑盒的函数)绝对保证只有一个浮点行为,在单独编译期间修复(这意味着没有发生全局优化)。
[请注意,这类似于字符串文字的定义方式:源代码中相同字符串文字的任何两次计算都可以引用相同或不同的字符数组。]
这意味着即使对于纯粹的应用函数,只有在不f(x) == f(x)
使用浮点运算(和字符串文字)(或者字符串文字的地址仅用于访问其元素)时才能保证基本相等。
因此,浮点运算具有非确定性语义,编译器为每个 FP 运算做出任意选择(这似乎比让编译器选择首先计算哪个子表达式 A 或 B 的小问题更不正常A+B
)。
似乎使用中间浮点值进行任何计算的函数不能用于任何需要满足 axioms的函子的 STL 容器或算法,例如
- 分类容器:
set
,map
,multiset
,multimap
- 散列容器
- 排序算法:
sort
,stable_sort
- 在排序范围上运行的算法:
lower_bound
,set_union
,set_intersection
...
由于所有二元谓词和散列函数在公理被构想之前必须是确定性的,因此它们必须是纯粹的应用性数学函数,具有所有可能输入的定义值,而 C++ 非确定性浮点中间值绝不是这种情况?
换句话说,浮点运算是否默认仅基于标准几乎不可用,并且只能在具有某些(模糊)确定性隐含保证的现实世界实现中使用?
glsl - 有没有办法在 Vulkan SPIR-V 中使用 OpenCL C mad 函数?
众所周知,至少有两种计算方法a * b + c
:
ret := a*b; ret := ret + c;
ret := fma(a, b, c);
但是在 OpenCL C 中,还有第三个函数称为“mad”,它以精度换取性能。
在 LunarG sdk 中,默认的 SPIR-V 编译器编译 GLSL 和 HLSL 着色语言,并且在 GLSL 规范 v4.60 中没有提到“mad”功能。
如何在 Vulkan 中使用“疯狂”功能?
c - 如何解决 vfmadd213ps 的“非法指令”?
我已经尝试过 AVX 内在函数。但它导致“test.exe 中 0x00E01555 处未处理的异常:0xC000001D:非法指令。”
我使用了 Visual Studio 2015。异常错误是在“vfmadd213ps ymm2,ymm1,ymm0”指令引起的。我尝试设置“/arch:AVX”和“/arch:AVX2”,但仍然导致错误。下面是我的代码。
以及在“vfmadd213ps ymm2,ymm1,ymm0”引起的错误。
那我做错了什么?操作系统是 win 7 64 位,CPU 是 Intel(R) Core(TM) i7-3520M CPU @ 2.90Ghz(4 个 CPU),~2.9Ghz。
c - 如何在 AVX 中使用融合乘法和加法来处理 16 位压缩整数
我知道在 AVX2 中可以使用一条指令进行乘加。我想使用乘加指令,其中每个 256 位 AVX2 变量都包含 16 个 16 位变量。例如,考虑下面的例子,
资源=a0*b0+a1*b1+a2*b2+a3*b3
这里 res、a0、a1、a2、a3、b0、b1、b2、b3 中的每一个都是 16 位变量。我密切关注讨论。请在下面找到我的代码来计算上面显示的示例,
cpucycles 代码来自ECRYPT,如下所示,
我的 gcc -version 返回,
我在用
当我在我的计算机上运行它时,我分别得到了 fma 方法和简单方法的以下循环
如您所见,FMA 方法稍微快一些,但我预计会更快。我知道在我的示例代码中存在许多内存访问,这可能是性能下降的原因。但,
当我转储程序集时,我看到两种方法的说明几乎相似。我在 FMA 版本中没有看到任何 fma 指令。我不明白原因。是因为 _mm256_mullo_epi16 指令吗?
我的方法正确吗?
你能帮我解决这个问题吗?
我是 AVX2 编程的新手,所以我很有可能做了一些不是很标准的事情,但我很乐意回答一些不清楚的事情。我提前感谢大家的帮助。
ieee-754 - FMA 和 naive a*b+c 的区别?
在 FMA(3) 的 BSD 库函数手册中,它说“这些函数计算 x * y + z”。
那么 FMA 和执行 x * y + z 的简单代码有什么区别?以及为什么 FMA 在大多数情况下都有更好的性能?
c++ - AVX2:计算 512 个浮点数组的点积
我将首先说我是 SIMD 内在函数的完整初学者。
本质上,我有一个支持 AVX2 内在 ( Intel(R) Core(TM) i5-7500T CPU @ 2.70GHz
) 的 CPU。我想知道计算两个std::vector<float>
size的点积的最快方法512
。
我在网上做了一些挖掘,发现了这个和这个,这个堆栈溢出问题建议使用以下函数__m256 _mm256_dp_ps(__m256 m1, __m256 m2, const int mask);
,但是,这些都暗示了执行点积的不同方法我不确定什么是正确(和最快)的方法它。
特别是,我正在寻找对大小为 512 的向量执行点积的最快方法(因为我知道向量大小会影响实现)。
谢谢您的帮助
编辑 1:我对-mavx2
gcc 标志也有点困惑。如果我使用这些 AVX2 函数,我是否需要在编译时添加标志?-OFast
另外,如果我编写一个天真的点积实现,gcc 是否能够为我做这些优化(比如如果我使用gcc 标志)?
编辑 2 如果有人有时间和精力,如果您能编写一个完整的实现,我将不胜感激。我相信其他初学者也会重视这些信息。
c++ - 将 FMA 指令用于 FFT 算法
我有一些 C++ 代码,随着时间的推移,它已经成为一个有用的 FFT 库,并且使用 SSE 和 AVX 指令使其运行得相当快。当然,这一切都只是基于 radix-2 算法,但它仍然成立。我最近想抓挠的是让蝴蝶计算与 FMA 指令一起工作。基本的 radix-2 蝴蝶由 4 个乘法和 6 个加法或减法组成。一个简单的方法是用 2 个 FMA 指令替换 2 个加减法和 2 个乘法,从而得到一个数学上相同的蝶形,但显然有更好的方法来做到这一点:
作者用 6 个 FMA 替换了所有 10 个加法、减法和乘法,前提是旋转因子的虚部除以实部。部分文本为“注意 cr1 != 0”。简而言之,这本质上是我的问题。数学似乎与宣传的所有旋转因子一样有效,除非真正的旋转为零,在这种情况下,我们最终除以零。在这里效率绝对至关重要,当 cr1 == 0 时将代码分支到不同的蝴蝶不是一个好的选择,特别是当我们使用 SIMD 一次处理多个 twiddles 和蝴蝶时,其中可能只有一个 cr1 == 的元素0. 我的直觉告诉我应该是这样,当 cr1 == 0 时,cr1 和 ci1 应该完全是其他一些值,并且 FMA 代码仍然会产生正确的答案,但我似乎无法弄清楚这一点。如果我能弄清楚,修改 FMA 蝴蝶的预先计算的旋转因子将是一件相对简单的事情,当然,我们也可以避免蝴蝶开始时的除法运算。