请考虑以下代码:
#include <cmath>
#include <cstdio>
const int COUNT = 100000000;
int main()
{
double sum = 0;
for (int i = 1; i <= COUNT; ++i)
sum += sqrt(i);
printf("%f\n", sum);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它在我的电脑上运行5.5秒.但是,如果我改变sqrt
成std::sqrt
,它将仅0.7秒运行.
我知道,如果我使用sqrt
,我正在使用C库中的函数,如果我使用std::sqrt
,我正在使用它<cmath>
.
但<cmath>
没有定义一个int
,如果我改变的类型i
进入double
,他们会为相同的速度运行.所以编译器没有优化int
.这似乎只发生sqrt
在Windows中.
那么为什么std::sqrt
比sqrt
其他功能快得多?为什么在Linux中他们不是?
具体来说,这是我正在讨论的代码:
float InvSqrt(float x) {
float xhalf = 0.5f*x;
int i = *(int*)&x; // warning: strict-aliasing UB, use memcpy instead
i = 0x5f375a86- (i >> 1);
x = *(float*)&i; // same
x = x*(1.5f-xhalf*x*x);
return x;
}
Run Code Online (Sandbox Code Playgroud)
我忘了我从哪里得到这个,但它显然比原来的 Quake III 算法(魔法常数略有不同)更好、更高效或更精确,但这个算法创建以来已经有 20 多年了,我只是想知道它是否是就性能而言,或者如果有一条指令已经在现代 x86-64 CPU 中实现了它,那么仍然值得使用它。
为什么sqrt
PHP中的输出不是"16"的整数?
例
php > $fig = 16;
php > $sq = sqrt($fig); //should be 4
php > echo $sq;
4
php > echo is_int($sq); // should give 1, but gives false
php >
Run Code Online (Sandbox Code Playgroud)
我觉得问题出在内部表示中,PHP隐藏的内容与Python类似.那么你怎么知道在取平方根后给定的数字是整数?
那么如何在不使用正则表达式的情况下区分PHP 4
和4.12323
PHP?
CPU周期(或者,实质上,"速度")之间有什么不同
x /= y;
Run Code Online (Sandbox Code Playgroud)
和
#include <cmath>
x = sqrt(y);
Run Code Online (Sandbox Code Playgroud)
编辑:我知道操作不等同,我只是随意提出x /= y
作为基准x = sqrt(y)
我正在尝试为有效的平方根算法找到更多信息,这些算法最有可能在FPGA上实现.已经发现了很多算法但是哪一个例如来自Intel或AMD?有效率我的意思是它们要么非常快,要么它们不需要太多内存.
编辑:我应该提一下,问题通常是一个浮点数,因为大多数硬件都实现了IEEE 754标准,其中数字表示为:1符号位,8位偏置指数和23位尾数.
谢谢!
我有一个高频运行的控制回路,需要在每个周期计算一个平方根.典型的平方根函数工作正常但需要花费过多时间.由于我采用平方根的值在每个周期上没有太大变化,我想找到一个迭代的平方根,它将收敛然后跟踪正确的结果.这样我就可以在每个时间步进行一次迭代,而不是很多次迭代.
问题是,当输入发生变化时,我看到的所有迭代平方根方法都可能会失败.特别是当输入变为零然后再次增加时,看起来会出现问题 - 方法不喜欢从零开始猜测.
我的输入范围是0-4.5,我需要大约0.01精密所以用的0.01递增/递减可能需要的时间太长了 - 我想这主要是在10次以内收敛.
仅供参考我使用16/32bit定点输入为16bit q12.它在微控制器上,所以我对使用1K查找表不感兴趣.代码也是从simulink模型生成的,它们的表查找功能相当充满了开销.
有一个很好的解决方案吗?
我发现自己在打字
double foo=1.0/sqrt(...);
Run Code Online (Sandbox Code Playgroud)
很多,我听说现代处理器有内置的反平方根操作码.
是否存在C或C++标准库的反平方根函数
1.0/sqrt(...)
吗?1.0/sqrt(...)
?有什么区别x**(1/2)
,math.sqrt()
和cmath.sqrt()
?
为什么cmath.sqrt()
单独得到二次方的复杂根?我应该专门用于我的平方根吗?他们在背景中的做法有何不同?
我们发现要替换的各种技巧std::sqrt
(Timing Square Root)和一些std::exp
(使用更快的指数近似),但我找不到任何可替代的东西std::log
.
它是我程序中循环的一部分,它被多次调用,而exp和sqrt被优化,英特尔VTune现在建议我进行优化std::log
,之后似乎只有我的设计选择才会受到限制.
现在我使用的第三阶泰勒近似ln(1+x)
与x
之间-0.5
和+0.5
(对于4%最大误差的情况下的%90)和回退到std::log
否则.这让我加速了15%.
我被告知这个代码片段相当于 (int)sqrt(n)
int s(int n) {
for (int i = 1, k = 0; n > 0; i += 2) {
if (k + i > n)
return i / 2;
k += i;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它似乎工作,但我不明白它是如何工作的?
sqrt ×10
math ×5
c++ ×4
c ×2
algorithm ×1
cpu-cycles ×1
cpu-time ×1
double ×1
estimation ×1
function ×1
hardware ×1
iteration ×1
logarithm ×1
mingw ×1
optimization ×1
performance ×1
php ×1
python ×1
square-root ×1
x86-64 ×1