我必须计算两个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]
3条答案
按热度按时间bbuxkriu1#
一般来说,当您以最明显地传达意图的方式编写源代码时,编译器通常会生成最优化的程序集。这就是你想要做的:
你可以看到一些编译器如何在Godbolt上编译它。特别是GCC有一个有趣的序列,它不使用任何分支或CMOV指令:
它使用的技巧是,我们可以通过对寄存器进行符号扩展,将上半部分与下半部分进行异或,然后从下半部分中减去上半部分,来获取寄存器的绝对值。同时,Clang使用CMOV指令。我不知道哪一个在实践中更好。您可能需要根据您所针对的特定体系结构对它们进行基准测试。
由于这是一个常见的操作,我怀疑是否有任何汇编程序可以比这两种方法编写得更快。
aemubtdh2#
如果你能负担得起时间-空间的权衡,它只需要64 K来保存一个结果的查找表。
也许缓存未命中将使这不值得。但是如果你在一个内部循环中使用这个宏,那么在这段时间内,它可能会把大部分内容保存在缓存中。
13z8s7eq3#
您可以在没有分支的情况下执行此操作,如下所示:
将每个值乘以相应的比较结果,结果会在您不希望的情况下减少为0。