首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >截断底流的Char减法

截断底流的Char减法
EN

Stack Overflow用户
提问于 2019-12-13 11:29:41
回答 3查看 103关注 0票数 3

是否有办法计算:

代码语言:javascript
复制
/** clipped(a - b) **/
unsigned char clipped_substract(unsigned char a, unsigned char b)
{
    return a > b ? a - b : 0;
}

使用一些二进制操作而不是测试?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-13 11:39:55

代码语言:javascript
复制
/** 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);
}
票数 0
EN

Stack Overflow用户

发布于 2019-12-13 12:14:22

原始函数编译为条件移动,不受性能问题的影响。您正在尝试在这里执行过早优化,这对您绝对没有好处。编写可读的代码,然后分析它,然后识别和优化性能瓶颈。

你说“测试可以降低性能”。如果你想做这样的微观优化,你应该把目标放在理解这些经验法则背后的原因,而不是把它们作为无条件的真理。

降低“测试”性能的是(错误预测)控制流分支。现代CPU大量使用指令流水线,控制流分支意味着不清楚下一步是哪个指令。通常的方法是CPU猜测(使用分支预测硬件/算法)分支的方向。如果它弄错了,它必须冲洗整个管道,并重新填充它,这浪费了循环。

嗯,有关的代码没有这样的问题。它编译成一个有条件的移动:

https://godbolt.org/z/upkgok

代码语言:javascript
复制
clipped_substract(unsigned char, unsigned char):
    mov     eax, edi
    mov     edx, 0
    sub     eax, esi
    cmp     dil, sil
    cmovbe  eax, edx
    ret

您可以看到这里没有控制流分支。有关不受上述性能问题影响的原因,请参见为什么有条件的移动不容易导致分支预测失败?

重复一遍:编写可读的代码,然后分析它,然后识别和优化性能瓶颈。这里您尝试的是修复一段根本不存在的性能问题代码(更不用说您没有证明该代码的性能甚至与程序的性能相关)。

票数 8
EN

Stack Overflow用户

发布于 2019-12-13 12:26:56

使用clang 11.0,编译器优化启用

代码语言:javascript
复制
unsigned char clipped_substract(unsigned char a, unsigned char b)
{   
    long c = b - a;
    return ((unsigned long)c >> (sizeof(c)*8-1)) * c;
}

尽管任何替代方案所花费的时间都会被忽略地不同,但是在执行10000000迭代时,其他方法在我的机器上占用0.300secs,而这个解决方案需要0.200secs

但是,只有当您使用一个大小大于char的类型时,这才是有效的,例如,这里我使用了long。我不记得charlong的确切定义,但我知道在我的机器上longchar更广泛。因此,相应地调整它。

基本上,我只是把减法的结果存储在一个更大的宽度变量中。如果结果为负值,则最重要的位将是1 else 0

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59321713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档