在C++中使用位运算符还是if语句更快
Is it faster to use bit operators or if statements in C++?
我在某个地方读到,尽可能使用按位运算符而不是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;
仅供参考,红色、绿色和蓝色是uint16_t 类型的成员变量
给定以下代码:
#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);
}
我的编译器会给出什么结果
Clang on OS X将为v1
和v2
生成功能相同的代码。唯一的区别是对min()
的调用和v1
中的等效工作的顺序不同。
在这两种情况下,都没有分支。
摘要:
编写最容易理解的代码。使用函数和语言功能以可读的方式表达代码。您的位代码是否比min()
函数可读性更强?
在几乎所有情况下,"更快"在很大程度上取决于目标系统和所使用的编译器,以及运算符如何过载。不过,在这种情况下,我非常怀疑会有那么大的区别,因为您仍然使用比较运算符,这应该是比简单的if
分支更昂贵的操作。
不过,上面列出的代码让我很困扰。对比较运算(布尔值运算,除非你重写了运算符)的结果取反对位或你正在做的事情来说都不安全。此外,它很难理解,这意味着以后很难对其进行维护。不过,if
版本解释了发生了什么。
要知道,您必须测量(评测代码)。
关于按位操作可能更快的理论是,分支预测失败可能会对性能造成重大影响。通过使用逐位操作而不是控制流开关,您可能能够完全避免条件分支,因此您永远不会错过分支预测。
根据具体情况,它可能对缓存更友好,而不是分支。
但除非你进行测量,否则你不会知道实际效果。有太多因素在起作用,无法简单地分析代码。
这就是三十年前的微优化,因为它可以节省微秒。今天我称之为纳米优化:-)
除非你有理由相信速度会影响到任何人,否则就做可读性更强的事情。
如果速度很重要,例如,因为您每秒需要处理60张1000万像素的图像,那么您可以尝试各种方法并测量执行时间。确切的速度将取决于编译器、处理器,有时纯粹取决于运气好还是坏。显然,您使用的编译器优化设置与生产代码中使用的设置相同。
在不同的处理器上,哪种代码产生最快的结果可能会有所不同。因此,你将所有变体都留在源代码中(包括可读性最强的变体),并使用#ifdef从你测量过的已知最快的变体中选择。假设你的代码应该在三个当前设备和五个未来设备上运行。你在目前的两台设备上进行了测量。然后,您要确保在这两个设备上运行的是最快的代码。在其他设备上,这是一个判断。如果A在处理器X上比B快40%,但在处理器Y上慢5%,那么你可能会在所有没有测量速度的处理器上使用A。然后将测量结果添加为注释。
现在,所有这些都是大量的工作,所以只有在节省的时间值得付出的情况下,你才能这样做。
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- If语句在c++中被忽略
- 比较if语句中的数组值和int值
- 以在Qt中的IF语句中设置时间延迟
- Craps游戏问题,忽略if语句
- c++:定义if语句中的模板
- C++嵌套的 If 语句中,它无法按预期工作
- 如果条件不相关,我应该更喜欢两个 if 语句而不是 if-else 语句吗?
- 需要有关此 if 语句的帮助
- 转换器练习:跳过 if 语句和 if 语句
- 避免在 C++ 中的 if 语句中递增
- 如果仍然不满足要求,如何使 if 语句重复?
- do while 循环中的 if 语句以 yes 或 no 结尾
- 为什么在此C++代码中触发此 if 语句?
- 如何基于平台在制作文件中制作if语句?
- 在 if 语句中使用 GetKeyState 时,它会跳过条件
- C++ If 语句,从其他语句重复