可以通过消除 >= 比较的需要,将带符号的双关符号类型转换为无符号整数来加快边界检查速度吗?

Could type punning signed to unsigned integers make bounds checking faster by eliminating the need for >= comparison?

假设我的程序中有一个非常关键的性能循环,我需要检查一个点是否在矩形内,但我知道在编译时下限总是为 0,如下所示: (x >= 0 && y >= 0 && x < width && y < height)

我可以通过将 x 和 y 类型双关为无符号整数来消除前两个比较吗(例如在 C++ 中使用 reinterpret_cast<>()union 之类的东西),因为符号位可以保证任何负数都会变成 unsigned int 大到足以使边界检查失败?如果是这样,您将如何用 C++ 或其他语言实现它?这样做你能获得任何性能提升吗?

也许……

虽然在 "paper" 上,这似乎只允许您执行两次比较而不是四次比较(这很好)- 您不能保证这将如何执行。现在大多数 CPU 都可以同时执行多个并行操作 - 而且您拥有的四个比较很容易并行计算。

您的问题取决于编译器,CPU 以及检查前后的代码 - 所以我的回答是 "maybe"。

避免将 x,y 转换为与当前大小不同的类型 - 即从 int8_t 转换为 uint8_t 是可以的,从 int8_t 转换为 uint32_t 可能 会受到处罚。

随心所欲重写:

if ( ( static_cast<uint8_t>(x) < width ) &&
     ( static_cast<uint8_t>(y) < length ) )

测试性能增量非常困难,您需要使用 RDTSC 指令用一些程序集包装您的代码,以捕捉前后的时间。您可能还需要使用 CPUID 指令来刷新管道。

简而言之,对我来说,您的优化似乎 合理,但可能不会产生太多效果。不过它会起作用的。

是的,当您测试有符号整数且下限为零时,这是一个完全有效的优化。事实上,这是一个非常常见的优化,您的编译器几乎肯定会自动执行它;自己动手混淆代码很可能是毫无意义的过早优化。

我刚刚在 GCC 4.9 上对此进行了测试,并通过检查生成的汇编代码确认它在 -O1 及更高版本时自动执行此优化。我希望所有现代编译器都这样做。