gpt4 book ai didi

assembly - XNOR 8 位 block 中的两个 64 位寄存器

转载 作者:行者123 更新时间:2023-12-03 16:46:44 27 4
gpt4 key购买 nike

我有两个 64 位值,我想按如下方式对它们进行 XNOR:

RAX: 01000001 | 01000010 | 01000011 | 01000001 | 01000101 | 01000110 | 01000111 | 01000001     XNOR
RBX: 01000001 | 01000001 | 01000001 | 01000001 | 01000001 | 01000001 | 01000001 | 01000001
-------------------------------------------------------------------------------------------
RCX: 1 0 0 1 0 0 0 1



XNOR does the following:
1 XNOR 1 | 1
1 XNOR 0 | 0
0 XNOR 1 | 0
0 XNOR 0 | 1
以便每次 XNOR 结果都恰好是 0xff它输出 1在 RCX 寄存器中相应的块位置。
是否有 I64 指令或算术/逻辑表达式来解决上述问题?

最佳答案

其中的“8 位块”部分使其与按位 XNOR 非常不同。并且您希望使用 AND 以 8 位块的形式水平减少 XNOR 结果。 这是什么SIMD都是关于 .
您想要的特定操作是比较相等性。幸运的是,x86 SSE2(或 MMX) pcmpeqb xmm0, xmm1 正是这样做的,在比较相等的元素中产生 0xFF (-1),在其他元素中产生 0x00。您可以 movq xmm0, src设置它,将 8 字节零扩展加载到 16 字节 XMM 寄存器中。
您可以使用 movq rcx, xmm0 将结果(来自 XMM0 的低 8 个字节)放入 RCX , 其中一个 bsf rcx, rcx将找到最低非零位的位置。或 test rcx, rcx如果有任何非零位,会让你分支。
如果你想要 RCX = 0x0100000100000001 (即每个字节底部的 1 位),您可以使用 SSSE3 pabsb xmm0, xmm0 在 MOVQ 之前对字节进行压缩绝对值,映射 0xFF -> 1 并保持 0 不变。与 SSE2 不同,这不是 x86-64 的基准,但缺少它的 CPU 已经完全过时了(例如 AMD Phenom II 是最新的)。

将 SIMD 比较结果转换为整数 reg 的正常方法是 pmovmskb . 它和 movq r, x 一样高效但让您无需使用 64 位寄存器即可获得所有 16 字节元素。

    movq     xmm0, [rdi]       ; 8-byte load.  Use movdqu for all 16 bytes
movq xmm1, [rsi]
pcmpeqb xmm0, xmm1
pmovmskb ecx, xmm0

cmp ecx, 0xffff
je all_were_equal

test cl, cl ; low 8 bytes of compare result -> low 8 bits of RCX
jnz some_were_equal
这需要每个字节的高位。即给你一个比较位图。您可以 bsf ecx, ecx查找 16 个字节中的哪个(如果有)是第一个匹配项。 (如果您的输入是零扩展的 8 字节值,则第 9 个字节将始终匹配。CH 将从 pmovmskb 输入的上半部分开始。)
当然,您可以简单地对其进行分支,而不是对比较结果进行位扫描。常用的方法有:
  • test ecx, ecx/jnz如果任何元素比较为真,则跳转
  • cmp ecx, 0xffff/je如果全部匹配则跳转。

  • 相关: Compare 16 byte strings with SSE使用内在函数执行此操作。

    你可以用 MMX movq mm0, [rdi] 来做到这一点/ pcmpeqb mm0, [rsi] ,但 MMX 在一些最新的 CPU 上的吞吐量比 SSE2 差(例如 Skylake 上的执行端口更少),你需要一个慢速 emms当您完成将 x87 状态恢复到 x87 模式时。
    尽管如此,您还是会保存一个 movq如果您的数据自然是 8 字节的块,那么您自然不能一次只处理 16 个字节。并且指令更紧凑(机器代码大小),您可以在英特尔手册中看到它们的编码。因此,如果 8 字节块非常适合,并且您可以将 EMMS 从足够大的循环中提取出来,那么 MMX 值得考虑。 (或者,如果您绝对从不使用 x87 指令,甚至不调用任何库函数,并且可以跳过 EMMS)

    关于assembly - XNOR 8 位 block 中的两个 64 位寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66463691/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com