- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
现代 x86_64 CPU 上的 AVX/SSE 求幂需要多少个时钟周期?
我是关于:pow(x, y) = exp(y*log(x))
即exp()
和 log()
AVX x86_64 指令都需要特定的已知周期数吗?
_mm256_exp_ps()
_mm256_log_ps()
或者循环数可能会根据指数级而变化,是否有最大循环数可以消耗指数?
最佳答案
x86 SIMD 指令集(即不是 x87),至少到 AVX2,不包括 SIMD exp
、log
或 pow
pow(x,0.5)
除外,它是平方根。
然而,有一些 SIMD 数学库是根据具有这些函数(以及其他函数)的 SIMD 指令构建的。英特尔的 SVML 包括:
__m256 _mm256_exp_ps(__m256)
__m256 _mm256_log_ps(__m256)
__m256 _mm256_pow_ps(__m256, __m256)
英特尔虚伪地称其为内在函数,而实际上它们是通过多条指令运行的。 SVML 是闭源且昂贵的。但是,通过在安装英特尔 OpenCL 运行时后搜索 svml,我在 OpenCL 目录中找到了一些 svml 文件,因此我认为您可以通过英特尔的 OpenCL 运行时间接获取 SVML。
AMD 还提供了一个名为 LibM 的 SIMD 数学库,它是封闭源代码但免费的,它也有自己的 SIMD 数学函数:
__m128 amd_vrs4_expf(__m128)
__m128 amd_vrs4_logf(__m128)
__m128 amd_vrs4_powf(__m128, __m128)
阿格纳雾的 Vector Class Library为 SVML 和 LibM 提供接口(interface)。请参阅文件 vectormath_lib.h
。从这里您可以找出来自 SVML 和 LibM 的相应功能。
Agner 还为这些功能提供了他自己的代码,他声称这些代码可以与专有的 Intel 和 AMD 版本竞争。对于函数的 Agner 版本,请查看 vectormath_exp.h
例如查看 exp_f
、log_f
和 pow_template_f
,然后查看生成的程序集。
可以使用SVML、LibM、Agner自带的函数对exp
和log
函数进行计时。但是,您应该知道 SVML 和 LibM 在其他硬件上运行不佳。例如,AMD 针对 Intel 没有的 FMA4 进行了优化(但 Intel 最初计划拥有 FMA4,然后在 AMD 已经计划 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 指令集是公开可用的,因此您可以构建自己的 exp
和 log
函数,而这正是 Agner 所做的。
更新
Glibc 2.22(应该很快就会出来)有一个 vector 数学库叫做 libmvec
.显然它从 -O1
以及 -ffast-math
和 -fopenmp
开始启用。我不确定为什么 fast-math
和 OpenMP 是必需的(特别是在下面的示例中,因为关联数学不是必需的)但是最终在 GNU C 标准库中有一个 SIMD 数学库真是太好了。
//gcc ./cos.c -O1 -fopenmp -ffast-math -lm -mavx2
#include <math.h>
int N = 3200;
double b[3200];
double a[3200];
int main (void)
{
int i;
#pragma omp simd
for (i = 0; i < N; i += 1)
{
b[i] = cos (a[i]);
}
return (0);
}
关于c++ - 在现代 x86_64 CPU 上,AVX/SSE 求幂需要多少个时钟周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31502095/
我在编写数学函数时遇到了麻烦。它应该接受 3 个变量并像这样计算方程。 答案 = x(1 + y/100)^ z 我把它写成: public compute_cert (int years, doub
我正在开发一个计算器,以便更好地学习 Java。我编写了自己的代码来使用 BigDecimal 参数计算幂。截至目前,代码无法处理分数幂,例如 2^2.2。为了解决这个问题,我想在我的代码中实现指数恒
我正在寻找一种算法(或者更好的是,代码!)来生成幂,特别是奇数指数大于 1 的数字:三次幂、五次幂、七次幂等等。然后我想要的输出是 8, 27, 32, 125, 128, 216, 243, 343
在 Codewars 上找到这个。该函数接受两个参数 A 和 B,并返回 A^B 的最后一位。下面的代码通过了前两个测试用例,但不会通过下一个测试用例。 def last_digit(n1, n2):
像 2^(2%1) 这样的表达式在 GHCi 中不会进行类型检查,并且错误消息是神秘的。为什么这不起作用,我需要改变什么? 我无法转换为其他类型,我希望将其用于 27^(1%3) 等表达式。 最佳答案
我的二次幂没有达到应有的水平,所以我想也许我可以 #define 做点什么。 不幸的是,我在预处理器指令方面经验不足,我不知道如何做 for 循环之类的事情。我看了看: http://www.cplu
如何在 Math.net 中获得三角函数的幂? Expr x = Expr.Variable("x"); Expr g = (2 * x).Sinh().Pow(2); g.ToString()给出输
我正在尝试拟合这个渐近接近零(但从未达到它)的数据。 我相信最好的曲线是逆逻辑函数,但欢迎建议。关键是预期的衰减“S 曲线”形状。 这是我到目前为止的代码,以及下面的绘图图像,这是一个非常丑陋的适合。
这个问题在这里已经有了答案: The most efficient way to implement an integer based power function pow(int, int) (2
我试图获得指数非常大的 double 值的幂(Java BigInteger 可以包含它(指数),例如:10^30 ) 也就是说,我想找到类似 1.75^(10^30) 或 1.23^(3423453
我有一个数学表达式,例如: ((2-x+3)^2+(x-5+7)^10)^0.5 我需要更换 ^符号到pow C语言的功能。我认为正则表达式是我需要的,但我不知道像专业人士那样的正则表达式。所以我最终
这是我的 previous question on bit flags 的后续内容,我澄清了一些重大误解。 我需要创建这些函数来查找包含零个或多个标志的 int 中的单个位标志: BitBinaryU
我已经在 java 中为 BigInteger 尝试过 modPow() 函数。 但它需要太长时间。 我知道模乘法,甚至也知道求幂。 但由于条件限制,我无法解决这个问题。 a、b 的值可以包含 100
我是一名优秀的程序员,十分优秀!