【发布时间】:2017-02-04 20:32:42
【问题描述】:
考虑一下这个简单的代码:
#include <complex.h>
complex float f(complex float x) {
return x*x;
}
如果您使用英特尔编译器使用-O3 -march=core-avx2 -fp-model strict 编译它,您会得到:
f:
vmovsldup xmm1, xmm0 #3.12
vmovshdup xmm2, xmm0 #3.12
vshufps xmm3, xmm0, xmm0, 177 #3.12
vmulps xmm4, xmm1, xmm0 #3.12
vmulps xmm5, xmm2, xmm3 #3.12
vaddsubps xmm0, xmm4, xmm5 #3.12
ret
这比你从gcc 和clang 得到的代码要简单得多,也比你在网上找到的用于复数相乘的代码要简单得多。例如,它不会显式地处理复杂的 NaN 或无穷大。
这个程序集是否符合 C99 复数乘法的规范?
【问题讨论】:
-
您使用的是什么版本的英特尔编译器?
-
@PaulR 17 via Godbolt。
-
@Zboson 这就是问题中的代码。
-
@eleanora,我知道这是问题中的代码。我添加了链接以防有人想玩它。
-
如果你的目标是效率don't use
complex。恕我直言,添加到 C 中的是愚蠢的类型,因为 Fortran 具有复杂的类型。我喜欢 C 的一个原因是类型是原始的,并且通常直接映射到程序集中的寄存器。但是complex是一种复合类型,类似于 C++ 中的类。使用 C 语言似乎很奇怪。我想有硬件可以直接实现复杂类型,但我从未使用过任何我所知道的。
标签: c assembly complex-numbers avx icc