我必须在对效率极其敏感的代码区域中计算两个 uint8_t
变量之间的差异。我必须找到执行此计算的最快方法。这是针对在 Ubuntu 上运行的用 C++ 编写的程序。
我目前使用以下宏:
#define UINT8_T_DIFF(a, b) (static_cast<uint8_t>(((a > b) ? (a - b) : (b - a))))
这个宏产生了我需要的答案,但我想知道我是否可以做些什么来使这个计算更快?
请注意,我在宏中有 static_cast
,因为如果没有它,我会收到一条编译器消息:
conversion to 'uint8_t {aka unsigned char}' from 'int' may alter its value [-Werror=conversion]
非常感谢任何和所有建议!非常感谢!
作为一般规则,当您以最明显地传达您的意图的方式编写源代码时,编译器通常会生成最优化的程序集。这就是你想要做的:
uint8_t diff(uint8_t a, uint8_t b) {
return abs(a - b);
}
您可以在 Godbolt 上看到一些编译器如何编译它.特别是 GCC 有一个有趣的序列,它不使用任何分支或 CMOV 指令:
movzx eax, dil
movzx esi, sil
sub eax, esi
cdq
xor eax, edx
sub eax, edx
ret
这使用了一个技巧,我们可以通过对寄存器进行符号扩展、将上半部分与下半部分进行异或,然后从下半部分减去上半部分来获取寄存器的绝对值。同时,Clang 使用 CMOV 指令。我不知道哪个在实践中表现更好。您可能需要根据您的目标特定架构对它们进行基准测试。
由于这是一个常见的操作,我怀疑是否有任何可以手写的程序集比这两种方法都更快。