我在某个地方读到,在可能的情况下,使用位运算符比if语句更快。我正在做一个图像处理项目,我有各种方法来做像素的数学。例如,当我添加一个像素时,我会检查并确保和不超过最大值。我把它改成这个..。
Pixel16 operator+(Pixel16 p) const noexcept
{
uint_fast32_t r = red + p.red;
uint_fast32_t g = green + p.green;
uint_fast32_t b = blue + p.blue;
return Pixel16(r | -(r > 0xffff), g | -(g > 0xffff), b | -(b > 0xffff));
}你们觉得这比写这样的陈述要快吗?
if(r > 0xffff)
r = 0xffff;FYI红色、绿色和蓝色是uint16_t类型的成员变量。
发布于 2015-04-23 15:46:53
鉴于这一守则:
#include <algorithm>
#include <cstdint>
struct Pixel16 {
uint16_t red;
uint16_t blue;
uint16_t green;
Pixel16(uint16_t red, uint16_t green, uint16_t blue);
};
Pixel16 v1(Pixel16 const & p, Pixel16 const & s) {
uint_fast32_t r = p.red + s.red;
uint_fast32_t g = p.green + s.green;
uint_fast32_t b = p.blue + s.blue;
return Pixel16(r | -(r > 0xffff), g | -(g > 0xffff), b | -(b > 0xffff));
}
Pixel16 v2(Pixel16 const & p, Pixel16 const & s) {
uint_fast32_t r = p.red + s.red;
uint_fast32_t g = p.green + s.green;
uint_fast32_t b = p.blue + s.blue;
r = std::min(r, (uint_fast32_t) 0xFFFF);
g = std::min(g, (uint_fast32_t) 0xFFFF);
b = std::min(b, (uint_fast32_t) 0xFFFF);
return Pixel16(r, g, b);
}因此,我的编译器提供了什么?
OS上的Clang将为v1和v2生成功能相同的代码。唯一的区别是对min()的调用和v1中的等效工作的顺序不同。
在这两种情况下,都没有分支。
摘要:
编写最容易理解的代码。使用函数和语言特性以可读的方式表示代码。您的按位代码是否比min()函数更易读?
发布于 2015-04-23 15:39:18
在几乎所有情况下,“更快”将在很大程度上取决于目标系统和所使用的编译器,以及操作符如何过载。不过,在这种情况下,我非常怀疑是否会有这么大的差别,因为您仍然在使用比较运算符,这应该比简单的if分支更昂贵。
不过,上面列出的代码让我很困扰。否定比较操作的结果(除非重写了运算符,否则为布尔操作)是不安全的,也不像您正在做的那样安全。此外,这是很难理解,这意味着它将是非常困难的人,以维持以后。然而,if版本解释了正在发生的事情。
发布于 2015-04-23 15:45:48
要知道,您必须测量(配置代码)。
关于按位操作可能更快的原因的理论是,分支预测失败可能会对性能造成重大影响。通过使用按位操作而不是控制流开关,您可以完全避免有条件的分支,这样就不会有分支预测丢失。
视情况而定,计算也可能比分支更容易缓存。
但除非你测量,否则你不会知道实际效果。有太多的因素影响到简单地分析代码。
https://stackoverflow.com/questions/29827978
复制相似问题