当前位置: 首页 > 知识库问答 >
问题:

海湾合作委员会中的 FMA3:如何启用

何骞尧
2023-03-14

我有一台i5-4250U,它有AVX2和FMA3。我正在Linux上测试我写的GCC 4.8.1中的一些密集矩阵乘法代码。下面是我编译的三种不同方式的列表。

SSE2:     gcc matrix.cpp -o matrix_gcc -O3 -msse2 -fopenmp
AVX:      gcc matrix.cpp -o matrix_gcc -O3 -mavx  -fopenmp
AVX2+FMA: gcc matrix.cpp -o matrix_gcc -O3 -march=native -fopenmp -ffast-math

SSE2和AVX版本在性能上明显不同。然而,AVX2 FMA并不比AVX版本好。我不明白这一点。假设没有FMA,我可以获得超过80%的CPU峰值翻转,但我认为我应该可以用FMA做得更好。矩阵乘法应该直接受益于FMA。我基本上是在AVX中一次做八个点积。当我检查mar=本地时,它会给出:

cc -march=native -E -v - </dev/null 2>&1 | grep cc1 | grep fma 
...-march=core-avx2 -mavx -mavx2 -mfma -mno-fma4 -msse4.2 -msse4.1 ...

因此,我可以看到它已启用(只是为了确保我添加了< code>-mfma,但这没有什么区别)。< code>ffast-math应该允许一个宽松的浮点模型如何将融合乘加(FMA)指令用于SSE/AVX

编辑:

根据Mysticial的评论,我继续使用_mm256_fmadd_ps,现在AVX2 FMA版本更快。我不确定为什么编译器不会为我这样做。对于超过1000x1000个矩阵,我现在获得了大约80 GFLOPS(不含FMA的峰值FLOPS的110%)。如果有人不相信我的翻牌峰值计算,这里是我做的。

peak flops (no FMA) = frequency * simd_width * ILP * cores
                    = 2.3GHZ    * 8          * 2   * 2     =  73.2 GFLOPS
peak flops (with FMA) = 2 * peak flops (no FMA)            = 146.2 GFLOPS

使用两个内核时,我在turbo模式下的CPU是2.3 GHz。ILP我得到2,因为Ivy Bridge可以同时执行一个AVX乘法和一个AVX加法(我已经展开循环几次以确保这一点)。

我只有55%的峰值失败率(FMA)。我不知道为什么,但至少我现在看到了一些东西。

一个副作用是,当我与一个我相信的简单矩阵乘法算法比较时,我现在得到一个小错误。我认为这是因为FMA只有一种舍入模式,而不是通常的两种(讽刺的是,这违反了IEEE浮点规则,尽管它可能更好)。

编辑:

有人需要重做如何实现每个周期4个FLOP的理论最大值?但使用Haswell,每个周期执行8个双浮点浮点运算。

编辑

实际上,Mysticial已经更新了他的项目以支持FMA3(见上面链接中他的回答)。我在装有MSVC2012的Windows8中运行了他的代码(因为Linux版本不支持FMA编译)。这是结果。

Testing AVX Mul + Add:
Seconds = 22.7417
FP Ops  = 768000000000
FLOPs   = 3.37705e+010
sum = 17.8122

Testing FMA3 FMA:
Seconds = 22.1389
FP Ops  = 1536000000000
FLOPs   = 6.938e+010
sum = 333.309

对于双浮点数,FMA3是69.38 GFLOPS。对于单浮点数,我需要加倍,所以是138.76 SP GFLOPS。我计算我的峰值是146.2 SP GFLOPS。这是峰值的95%!换句话说,我应该能够大大改进我的GEMM代码(尽管它已经比Eigen快了很多)。

共有2个答案

长孙骏
2023-03-14

现在,以下编译器选项足以将< code > _ mm 256 _ add _ PS(_ mm 256 _ mul _ PS(a,b),c)压缩为单个fma指令(例如< code>vfmadd213ps):

GCC 5.3:   -O2 -mavx2 -mfma
Clang 3.7: -O1 -mavx2 -mfma -ffp-contract=fast
ICC 13:    -O1 -march=core-avx2

我尝试了 /O2 /拱门:AVX2 /fp:用 MSVC 快速,但它仍然没有收缩(惊喜惊喜)。不过,MSVC将收缩标量操作。

GCC至少从GCC 5.1开始这样做。

尽管 -O1 足以满足某些编译器的这种优化,但始终至少使用 -O2 来获得整体性能,最好是 -O3 -march=本机 -flto 和配置文件引导优化。

如果这对您的代码来说没问题,那么-ffast-math

艾原
2023-03-14

这里只回答了问题的一小部分。如果你写了_mm256_add_ps(_mm256_mul_ps(areg0, breg0), tmp0),gcc-4.9处理它几乎就像内联ASM一样,不会对其进行太多优化。如果你用areg0*breg0 tmp0替换它,gcc和clang都支持这种语法,那么gcc开始优化,如果可用,可能会使用FMA。我对gcc-5进行了改进,例如,_mm256_add_ps现在被实现为一个内联函数,它只使用,因此具有内部函数的代码也可以优化。

 类似资料:
  • 我有一个关于GNU GCC中< code>-ffp-contract标志的问题(见https://GCC . GNU . org/online docs/GCC/Optimize-options . html)。 标志文档编写如下: < code>-ffp-contract=off禁用浮点表达式收缩。< code>-ffp-contract=fast启用浮点表达式收缩,如融合乘加运算的形成(如果目

  • ISO标准委员会,SC22 WG21,是在ISO规则下运行的。奇怪的是,这些规则并非标准化的,而是随着时间的变化而变化。(译注:标准委员会的规则并不标准) 大多数国家都有活跃的C++团体并形成了自己的国家标准。这些团体举行会议,通过网络协调一致,并向ISO会议推选代表。加拿大,法国,德国,瑞士,英国和美国是出席这些会议较多的国家。丹麦,荷兰,日本,挪威,西班牙和别的一些国家则是出席人数比较少的国家

  • 如何获取所有可用优化标志及其参数值的列表?像这样的东西 https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html,但在命令行上

  • 我正在做一个Kafka的消费者计划。最近我们在PROD环境下进行了部署。在那里,我们面临以下问题: 我的理解是,当组协调器不可用并被重新发现时,心跳间隔(根据文档为3秒)过期,消费者被踢出组。这是正确的吗?。如果是这样的话,应该为这个工作做些什么呢?。如果我错了,请帮助我理解这个问题,并建议您有任何想法,以解决这个问题。如果需要,我可以分享代码。

  • 标准委员会包括大约200个人,其中有大约60位会出席每年两到三次一周时间的会议。除此之外,在一些国家还有一些国家标准组织和会议。多数成员通过出席会议,邮件讨论或提交论文供标准委员会斟酌等方式贡献自己的力量。多数成员有朋友或同事提供帮助。第一天,标准委员会召集从各个国家而来的代表,并且每一次会议由6到12个国家的代表参加。最终投票由20个国家标准组织完成。这样,ISO C++标准是一个集合了众人集体

  • 图表秀有五种会员类型:普通会员、金会员、白金会员、钻石会员和企业会员。每种会员享有的特权不同,更高级的会员拥有更多的图表和高级功能。 购买步骤: 点击图表秀首页导航栏的“会员特权”,了解各种会员功能。 点击会员详情页下方的“购买”,了解会员价格,普通用户默认为普通会员。点击“立即充值”,进入会员充值页面。 或者,直接点击用户头像,在下拉框中点击“去续费”按钮,进入会员充值页面。 选择所需购买会员等