C++ 基准数学。h平方根和地震平方根
好的,所以我开始思考数学的速度。h平方根和那个有神奇数字的相比有多快 但这对我来说是一个受伤的世界 我第一次在Mac电脑上尝试这个,math.h每次都会轻而易举地赢,然后在Windows上,神奇的数字总是赢,但我认为这一切都是因为我自己的无知C++ 基准数学。h平方根和地震平方根,c++,g++,C++,G++,好的,所以我开始思考数学的速度。h平方根和那个有神奇数字的相比有多快 但这对我来说是一个受伤的世界 我第一次在Mac电脑上尝试这个,math.h每次都会轻而易举地赢,然后在Windows上,神奇的数字总是赢,但我认为这一切都是因为我自己的无知 在Mac上使用“g++-o sq_root sq_root_test.cpp”编译程序运行时,大约需要15秒才能完成。但在VS2005发布时编译只需一秒钟。(事实上,我必须在debug中编译,才能让它显示一些数字) 我可怜的人的基准?这真的很愚蠢吗?因为数
//sq\u root\u test.cpp
#包括
#包括
#包括
浮动invSqrt(浮动x)
{
联合{
浮动f;
int i;
}tmp;
tmp.f=x;
tmp.i=0x5f3759df-(tmp.i>>1);
浮动y=tmp.f;
返回y*(1.5f-0.5f*x*y*y);
}
int main(){
std::clock_u t start;/=std::clock();
标准:时钟结束;
漂浮在我的根上;
整数迭代次数=9999999;
// ---
rootMe=2.0f;
开始=标准::时钟();
std::cout您的基准测试有几个问题。首先,您的基准测试包括从int到float的可能昂贵的转换。如果您想知道平方根的成本,您应该基准平方根,而不是数据类型转换
其次,编译器可以(并且是)优化整个基准测试,因为它没有明显的副作用。您不使用返回值(或者将其存储在易失性内存位置),因此编译器认为它可以跳过整个过程
这里的一条线索是,您必须禁用优化。这意味着您的基准测试代码已被破坏。在基准测试时,千万不要禁用优化。您想知道哪个版本运行得最快,所以应该在实际使用的条件下对其进行测试。如果要在性能敏感的代码中使用平方根e、 您将启用优化,因此在没有优化的情况下它的行为是完全不相关的
此外,您不是在测试计算平方根的成本,而是在测试平方根的逆成本。
如果你想知道哪种方法计算平方根的速度最快,你必须将1.0/..
除法向下移动到Quake版本。(由于除法是一种非常昂贵的操作,这可能会对你的结果产生很大的影响)
最后,可能值得指出的是,Carmacks的小把戏是为了在12年前的计算机上快速运行而设计的。一旦你修复了基准测试,你可能会发现它不再是一种优化,因为今天的CPU在计算“真实”方面要快得多平方根。您运行g++
时没有进行优化,但在发布时运行VS2005(因此进行了优化)。这种比较是不公平的。谢谢,我以为我在g++上做错了什么。你是一块木头?只有一次,但那是很久以前的事了,所以不要反对我。谢谢,我应该提到我这样做,因为我在Uni与PS2一起工作。这几乎是一样古老的。不管怎样,PS2是一种与PC截然不同的体系结构年龄。
//sq_root_test.cpp
#include <iostream>
#include <math.h>
#include <ctime>
float invSqrt(float x)
{
union {
float f;
int i;
} tmp;
tmp.f = x;
tmp.i = 0x5f3759df - (tmp.i >> 1);
float y = tmp.f;
return y * (1.5f - 0.5f * x * y * y);
}
int main() {
std::clock_t start;// = std::clock();
std::clock_t end;
float rootMe;
int iterations = 999999999;
// ---
rootMe = 2.0f;
start = std::clock();
std::cout << "Math.h SqRoot: ";
for (int m = 0; m < iterations; m++) {
(float)(1.0/sqrt(rootMe));
rootMe++;
}
end = std::clock();
std::cout << (difftime(end, start)) << std::endl;
// ---
std::cout << "Quake SqRoot: ";
rootMe = 2.0f;
start = std::clock();
for (int q = 0; q < iterations; q++) {
invSqrt(rootMe);
rootMe++;
}
end = std::clock();
std::cout << (difftime(end, start)) << std::endl;
}