我目前正在用 C++ 编写一些像向量数学类的 glsl,并且我刚刚实现了一个abs()
像这样的函数:
template<class T>
static inline T abs(T _a)
{
return _a < 0 ? -_a : _a;
}
我将它的速度与默认的 C++ 进行了比较abs
from math.h
像这样:
clock_t begin = clock();
for(int i=0; i<10000000; ++i)
{
float a = abs(-1.25);
};
clock_t end = clock();
unsigned long time1 = (unsigned long)((float)(end-begin) / ((float)CLOCKS_PER_SEC/1000.0));
begin = clock();
for(int i=0; i<10000000; ++i)
{
float a = myMath::abs(-1.25);
};
end = clock();
unsigned long time2 = (unsigned long)((float)(end-begin) / ((float)CLOCKS_PER_SEC/1000.0));
std::cout<<time1<<std::endl;
std::cout<<time2<<std::endl;
现在默认的 abs 需要大约 25 毫秒,而我的需要 60 毫秒。我猜正在进行一些低级优化。有谁知道如何math.h
abs
内部工作?性能差异并不明显,但我只是很好奇!
由于它们是实现,因此它们可以自由地做出任意多的假设。他们知道格式double
并可以用它来玩把戏。
很可能(几乎不是一个问题),你的double
is the 二进制64格式 http://en.wikipedia.org/wiki/Double_precision_floating-point_format。这意味着符号有自己的位,绝对值只是清除该位。例如,作为一个专业,编译器实现者可以执行以下操作:
template <>
double abs<double>(const double x)
{
// breaks strict aliasing, but compiler writer knows this behavior for the platform
uint64_t i = reinterpret_cast<const std::uint64_t&>(x);
i &= 0x7FFFFFFFFFFFFFFFULL; // clear sign bit
return reinterpret_cast<const double&>(i);
}
这会消除分支并可能运行得更快。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)