trunk函数很慢
Is the trunc function very slow?
tl;dr:double b=a-(size_t)(a)
比double b=a-trunc(a)
快
我正在为图像实现一个旋转函数,我注意到trunc
函数似乎非常慢。
在对图像进行循环代码时,像素的实际影响会被注释掉,以便进行性能测试,所以我甚至不访问像素。
double sina(sin(angle)), cosa(cos(angle));
int h = (int) (_in->h*cosa + _in->w*sina);
int w = (int) (_in->w*cosa + _in->h*sina);
int offsetx = (int)(_in->h*sina);
SDL_Surface* out = SDL_CreateARGBSurface(w, h); //wrapper over SDL_CreateRGBSurface
SDL_FillRect(out, NULL, 0x0);//transparent black
for (int y = 0; y < _in->h; y++)
for (int x = 0; x < _in->w; x++){
//calculate the new position
const double destY = y*cosa + x*sina;
const double destX = x*cosa - y*sina + offsetx;
这是使用trunc
的代码
size_t tDestX = (size_t) trunc(destX);
size_t tDestY = (size_t) trunc(destY);
double left = destX - trunc(destX);
double top = destY - trunc(destY);
这是更快的等效
size_t tDestX = (size_t)(destX);
size_t tDestY = (size_t)(destY);
double left = destX - tDestX;
double top = destY - tDestY;
答案建议在转换回积分时不要使用trunc
,所以我也尝试过这种情况:
size_t tDestX = (size_t) (destX);
size_t tDestY = (size_t) (destY);
double left = destX - trunc(destX);
double top = destY - trunc(destY);
快速版本似乎平均需要30ms才能浏览完整图像(2048x1200(,而使用trunc
的慢速版本对同一图像大约需要135ms。只有两次调用trunc
的版本仍然比没有调用的版本慢得多(约100ms(。
就我对C++规则的理解而言,两个表达式应该总是返回相同的东西。我是不是遗漏了什么?dextX
和destY
被声明为const
,因此只应对trunc
函数进行一次调用,即使这样,它本身也无法解释慢三倍以上的因素。
我正在使用带有优化(/O2(的Visual Studio 2013进行编译。有什么理由使用trunc
函数吗?即使是使用整数来获得分数部分似乎也更快。
按照您使用它的方式,根本没有理由使用trunc
函数。它将一个二重转换为一个二重,然后将其转化为一个积分并丢弃。事实上,替代方案更快,这并不奇怪。
在现代x86 CPU上,int<->浮点转换非常快——通常会为转换生成内联SSE代码,成本大约为几个指令周期1
然而,对于trunc
,需要函数调用,并且函数调用开销本身几乎肯定大于内联float->int转换的开销。此外,trunc
函数本身可能相对昂贵-它必须完全符合IEEE-754,因此必须正确处理浮点值的整个范围,边缘情况也必须正确处理,如NaN、INF、分母、超出范围的值等。因此,总的来说,我预计trunc
的成本约为数十个指令周期,即比内联float->int转换的成本大一个数量级左右。
1.请注意,float<->int转换并不总是便宜的——其他CPU系列,甚至更旧的x86 CPU,可能不支持ISA进行这种转换,在这种情况下,通常会使用库函数,其成本与
trunc
类似。在这方面,现代x86 CPU是一个特例。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- trunk函数很慢