有没有办法计算:
/** clipped(a - b) **/
unsigned char clipped_substract(unsigned char a, unsigned char b)
{
return a > b ? a - b : 0;
}
使用一些二进制操作而不是测试?
/** clipped(a - b) **/
unsigned char clipped_substract(unsigned char a, unsigned char b)
{
return a - (a+b) / 2 + getAbs(a-b) / 2;
}
unsigned int getAbs(int n)
{
int const mask = n >> (sizeof(int) * 8 - 1);
return ((n + mask) ^ mask);
}
使用clang 11.0,启用编译器优化
unsigned char clipped_substract(unsigned char a, unsigned char b)
{
long c = b - a;
return ((unsigned long)c >> (sizeof(c)*8-1)) * c;
}
虽然任何替代方案所花费的时间都有显著不同,但当执行
<,而此解决方案大约需要0.200秒10000000
迭代时,其他方法在我的机器上大约需要0.300秒。
但这仅在使用大小大于< code>char
的类型时有效,例如这里我使用< code>long。我不记得< code>char或< code>long的确切定义,但我知道在我的机器上< code>long比< code>char更宽。所以要相应调整。
基本上,我只是将减法的结果存储在更大的宽度变量中。如果结果为负数,则最高有效位将为 1
else 0
。
原始函数编译为条件移动,不受性能问题的影响。您试图在此处执行过早的优化,这对您绝对没有好处。编写可读代码,然后对其进行分析,然后识别和优化性能瓶颈。
你说“考试会降低表现”。如果你想做这样的微优化,你应该致力于理解这些经验法则背后的原因,而不是把它们当作无条件的真理。
降低“测试”性能的是(预测失误的)控制流分支。现代CPU大量使用指令流水线,控制流分支意味着不清楚下一条指令是什么。常见的方法是CPU猜测(使用分支预测硬件/算法)分支的走向。如果它弄错了,它必须冲洗整个管道并重新填充,这会浪费循环。
好吧,有问题的代码没有这样的问题。它编译成有条件的移动:
https://godbolt.org/z/upkgok
clipped_substract(unsigned char, unsigned char):
mov eax, edi
mov edx, 0
sub eax, esi
cmp dil, sil
cmovbe eax, edx
ret
您可以看到这里没有控制流分支。了解为什么条件移动不易受到分支预测失败的影响?为什么不受制于上述性能问题。
我重复一遍:编写可读的代码,然后对其进行分析,然后识别并优化性能瓶颈。您在这里尝试的是修复一个根本不存在的性能问题代码(更不用说您没有证明这个代码的性能甚至与您的程序性能相关)。
考虑以下代码: 不管我怎么看,这种下溢似乎都没有意义。正如维基百科所说, 下溢是计算机程序中的一种情况,其中计算结果的绝对值比计算机实际存储在CPU内存中的数值小。 但很明显,计算机能够存储与所讨论的值大致接近的数字,因此定义似乎与我在这里看到的行为完全不一致。 有人能解释一下为什么其中一些会产生下溢而另一些不会吗? 这是正确的行为还是错误?
我试图在一个没有权限在WildFly主目录和子目录中写入的用户下启动WildFly 8.2。为此,我已经将目录复制到用户主目录。下面是我用来在cygwin中启动WildFly的命令: 这是这个命令的输出: 正如您在上面的日志中看到的,首先WildFly尝试写入,即使命令行中指出了另一个目录作为服务器基本目录。由于缺乏权限而无法在那里写入WildFly继续正常启动服务器。 有没有办法让WildFly
为什么Java可以推断出多个上限类型的共同祖先,而不能推断出下限类型的共同祖先? 更具体地说,请考虑以下示例:
问题内容: 我实际上有两个问题,但是让我先解决主要问题,因为我认为另一个更容易解决。 我在菜单左侧的滚动条的左侧有一个固定位置的div。右侧是可以正确滚动的标准div。问题是,当浏览器的视口太小而看不到整个菜单时,..没有办法让它滚动到我能找到的位置(至少没有使用CSS)。我试过在CSS中使用不同的溢出,但是没有什么可以使div滚动。包含菜单的div设置为min- height:100%和posi
我想打开一个模态层,超越身体滚动。为了实现这一点,当层被显示时,我将主体溢出设置为隐藏,溢出在模态层上滚动。从视觉上看,一个滚动条替换了另一个。 在背景中,我有一个固定位置和100%宽的顶栏。当主体溢出设置为隐藏时,100%宽度div(顶栏)占据滚动条空间,其元素向右移动。 如何防止这些元素移动? 我试图计算(javascript)滚动条的宽度,当设置body overflow:hidden时,给
问题内容: 我试图获取Java中的上溢和下溢异常,但找不到任何不错的教程。我特别想学习 它们彼此之间有何不同? 这些异常的子类是什么? 在哪种情况下会抛出它们? 其中哪些可以处理,如何处理? 与它们相关的最佳实践是什么? 任何指向有用教程的链接都可以 问题答案: 好的,OP曾经想了解堆栈溢出和算术溢出及其对应的下溢。开始.... 当数字太大而无法容纳其值类型时,就会发生算术溢出。例如,a 保持值介