假设我的程序中有一个非常性能关键的循环,我需要检查一个点是否在一个矩形内,但我知道在编译时下限总是为0,如下所示: (x >= 0 && y >= 0 && x < width && y < height)
我可以通过类型将x和y类型化为无符号整数来消除前两个比较(例如,类似于 reinterpret_cast<>()
或者a union
在C ++中),因为符号位会保证任何负数都会变成一个 unsigned int
大到足以使边界检查失败?如果是这样,你将如何用C ++或其他语言实现它?这样做可以获得任何性能提升吗?
是的,当您测试有符号整数并且下限为零时,它是完全有效的优化。实际上,这是一种常见的优化,您的编译器几乎肯定会自动执行它;通过自己动手来模糊代码很可能是一个毫无意义的过早优化。
我刚刚在GCC 4.9上对此进行了测试,并通过检查生成的汇编代码确认它自动执行此优化 -O1
以上。我希望所有现代编译器也能这样做。
也许...
虽然在“纸上”这似乎只允许你进行两次比较而不是四次(这很好) - 你无法保证这将如何表现。如今,大多数CPU可以同时执行多个并行操作 - 您可以轻松地并行计算四个比较。
你的问题取决于编译器,CPU以及检查前后的代码 - 所以我的答案是“也许”。
避免将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指令来刷新管道。
总之,对我来说你的优化 似乎 合理,但如果有的话,可能不会产生太大的影响。它会工作。