在现代x86_64 CPU上,AVX / SSE取幂的时钟周期是多少?
我的意思是:pow(x, y) = exp(y*log(x))
即。同时exp()
和log()
AVX x86_64指令是否需要一定的已知周期数?
_mm256_exp_ps()
_mm256_log_ps()
或者循环次数可能会根据指数级别而变化,是否有最大循环次数可以进行成本求幂?
答案 0 :(得分:8)
x86 SIMD指令集(即非x87),至少高达AVX2,不包括SIMD exp
,log
或pow
,{{1}除外这是平方根。
然而,有SIMD数学库是由具有这些功能的SIMD指令构建的(除此之外)。英特尔的SVML包括:
pow(x,0.5)
当英特尔实际上有几个指令功能时,英特尔不诚实地称之为内在函数。 SVML是封闭源和昂贵的。但是,通过在安装Intel OpenCL运行时搜索svml,我在OpenCL目录中找到了一些svml文件,所以我认为你可以通过Intel的OpenCL运行时间接获得SVML。
AMD还提供了一个名为LibM的SIMD数学库,它是封闭源但是免费的,它也有自己的SIMD数学函数:
__m256 _mm256_exp_ps(__m256)
__m256 _mm256_log_ps(__m256)
__m256 _mm256_pow_ps(__m256, __m256)
Agner Fog的Vector Class Library提供了SVML和LibM的接口。请参阅文件__m128 amd_vrs4_expf(__m128)
__m128 amd_vrs4_logf(__m128)
__m128 amd_vrs4_powf(__m128, __m128)
。从这里你可以找出SVML和LibM的相应功能。
Agner还为这些功能提供了他自己的代码,他声称这些代码与专有的Intel和AMD版本竞争。对于Agner的函数版本,请查看vectormath_lib.h
,例如查看vectormath_exp.h
,exp_f
和log_f
,然后查看生成的程序集。
您可以使用SVML,LibM和Agner自己的函数来计算pow_template_f
和exp
函数的时间。但是,您应该知道SVML和LibM在其他硬件上不能很好地运行。例如,AMD针对英特尔没有的FMA4进行了优化(但英特尔原计划在FMA4已经计划用于FMA4之后突然改为FMA4然后更改为FMA3)。 Intel appears to do something ummm...well I suggest you read about it
因此,如果您分别在AMD或Intel处理器上使用SVML或LibM,您可能会在性能上获得非常不同的结果(unless you manage to replace Intel's CPU dispatch function)。与GPU不同,x86指令集是公开可用的,因此您可以构建自己的log
和exp
函数,这就是Agner所做的。
<强>更新强>
Glibc 2.22(即将推出)有一个名为libmvec
的矢量数学库。显然,从log
开始,-O1
和-ffast-math
启用它。我不确定为什么-fopenmp
和OpenMP是必要的(特别是在下面的例子中,因为不需要关联数学)但最终在GNU C标准库中有一个SIMD数学库是很棒的。
fast-math