添加具有饱和度的 32 位字

发布于 2024-11-30 08:31:33 字数 73 浏览 1 评论 0原文

您知道使用 MMX/SSE 汇编指令对 32 位有符号字进行饱和添加的方法吗?我可以找到 8/16 位版本,但找不到 32 位版本。

Do you know any way to add with saturation 32-bit signed words using MMX/SSE assembler instructions? I can find 8/16 bits versions but no 32-bit ones.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁月无声 2024-12-07 08:31:33

您可以通过执行以下步骤来模拟饱和签名加法:

int saturated_add(int a, int b)
{
    int sum = a + (unsigned)b;                // avoid signed-overflow UB
    if (a >= 0 && b >= 0)
        return sum > 0 ? sum : INT32_MAX;     // catch positive wraparound
    else if (a < 0 && b < 0)
        return sum > 0 ? INT32_MIN : sum;     // catch negative wraparound
    else
        return sum;                           // sum of pos + neg always fits
}

未签名,它甚至更简单,请参阅此 stackoverflow 帖子

在 SSE2 中,上面映射到一系列并行比较和 AND/ANDN 操作。不幸的是,硬件中没有可用的单一操作。

You can emulate saturated signed adds by performing the following steps:

int saturated_add(int a, int b)
{
    int sum = a + (unsigned)b;                // avoid signed-overflow UB
    if (a >= 0 && b >= 0)
        return sum > 0 ? sum : INT32_MAX;     // catch positive wraparound
    else if (a < 0 && b < 0)
        return sum > 0 ? INT32_MIN : sum;     // catch negative wraparound
    else
        return sum;                           // sum of pos + neg always fits
}

Unsigned, it's even simpler, see this stackoverflow posting

In SSE2, the above maps to a sequence of parallel compares and AND/ANDN operations. No single operation is available in hardware, unfortunately.

沒落の蓅哖 2024-12-07 08:31:33

饱和无符号减法很容易,因为对于“a -= b”,我们可以

    asm (
        "pmaxud %1, %0\n\t" // a = max (a,b)
        "psubd %1, %0" // a -= b
        : "+x" (a)
        : "xm" (b)
    );

使用 SSE 来完成。

我一直在寻找无符号加法,但可能唯一的方法是转换为饱和无符号减法,执行它,然后转换回来。对于签名变体也是如此。

编辑:通过无符号加法,您可以通过这种方式得到 min (a, ~b) + b ,这当然是有效的。通过有符号加法和减法,您有两个饱和边界,这使事情变得复杂。

Saturated unsigned subtraction is easy, because for `a -= b', we can do

    asm (
        "pmaxud %1, %0\n\t" // a = max (a,b)
        "psubd %1, %0" // a -= b
        : "+x" (a)
        : "xm" (b)
    );

with SSE.

I was looking for unsigned addition, but possibly, the only way is to transform to a saturated unsigned subtraction, perform it, and transform back. Same for signed variants.

EDIT: with unsigned addition, you get min (a, ~b) + b this way, which of course works. With signed addition and subtraction, you have two saturation boundaries, which makes things complicated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文