C++ Arm霓虹灯和poly8_t和poly16_t

C++ Arm霓虹灯和poly8_t和poly16_t,c++,c,arm,neon,intrinsics,C++,C,Arm,Neon,Intrinsics,我最近一直在研究使用intrinsics的霓虹灯优化,我遇到了poly8_t和poly16_t数据类型。然后我就开始思考它们到底是什么 我已经搜索了整个网络,但到目前为止,还没有找到任何关于它们是什么的解释 谁能给我解释一下吗 编辑:感谢您的回答,但如果它只是一种不同的乘法方式等,为什么它的数据类型会完全不同呢?这些类型用于无进位乘法。它对于加密算法和CRC哈希和非常有用。以下是一些关于应用程序的白皮书(它们探讨了x86 PCLMULQDQ指令,但同样的思想也适用于在ARM处理器上进行较少的乘法

我最近一直在研究使用intrinsics的霓虹灯优化,我遇到了poly8_t和poly16_t数据类型。然后我就开始思考它们到底是什么

我已经搜索了整个网络,但到目前为止,还没有找到任何关于它们是什么的解释

谁能给我解释一下吗


编辑:感谢您的回答,但如果它只是一种不同的乘法方式等,为什么它的数据类型会完全不同呢?

这些类型用于无进位乘法。它对于加密算法和CRC哈希和非常有用。以下是一些关于应用程序的白皮书(它们探讨了x86 PCLMULQDQ指令,但同样的思想也适用于在ARM处理器上进行较少的乘法运算):


  • 左=正则乘法,右=无角乘法

            1 1 0 1                              1 1 0 1
         *  1 0 0 1                              1 0 0 1
       ------------        -->              --------------
         (1)1 1 0 1  <-- (1) is carry            1 1 0 1
          0 0 0 0                              0 0 0 0 
        0 0 0 0                              0 0 0 0
      1 1 0 1        +                     1 1 0 1         + GF(2) or XOR
      -------------                        ---------------
      1 1 1 0 1 0 1                        1 1 0 0 1 0 1
    
    正则多项式乘法为:p(x)*(x^3+1)=p(x)*x^3+p(x)==

    在GF(2)中,每个系数都是简单的模2计算,使得1100101b


    GF(2^8)的数据类型包含256个唯一的位模式,因此GF中的数据类型看起来就像uint8、uint16或最多128。但是,例如,位模式“0000001”没有传统的解释。(它不是17位小数,但可能是“单位”的123次方对其他多项式的模。)将这个数字与生成器多项式g(x)的相同“单位”模相乘,得到124次方,依此类推。然后,有限域的属性(标识)就有了有趣的应用——例如,人们可以(远程)轻松地计算要附加到文件中的32位数字,使其与32位CRC匹配;或者,可以使用这些属性并行化crc计算,或者在有限域中使用类傅立叶变换(数论变换)实现bignum乘法。

    作为参考,这来自第7.2.2章:

    多项式算法在实现某些加密时很有用 或数据完整性算法

    在{0,1}上添加两个多项式与按位排他相同 或多项式的附加结果会使a的值不同 常规添加

    将两个多项式相乘于{0,1}首先需要确定 传统乘法中的部分积,然后是部分积 产品是排他性的,而不是按常规添加。 多项式乘法的结果与传统乘法不同 乘法,因为它需要部分的多项式加法 产品


    您没有描述PMUL vs PMULL

    正如我所理解的(可能是错误的)每个元素 PMUL处理两个8位源元素并生成一个 8位结果元素

    每个元素PMUL生成8个部分产品和 每个PP在XORD之前分别移位。所以从 从第一个PP的lsb到最后一个PP的msb。 似乎有15位的结果。PMUL只能存储 8位结果


    15位结果中最重要的7位是否被丢弃?

    我认为用于多项式乘法。从以下行搜索“多项式乘法霓虹灯:
    typedef short poly16\t@self:这并没有说明它们是什么……我会检查它们是如何实际使用的——它们是如何转换为汇编指令的。还有Gouvêa和López。哪条指令在ARM上的乘法运算更少?ARM在这里必须指Cortex A7或A8处理器,其中包括NEON扩展。我认为它是ARMv7中的
    VMUL.P8
    @auselen指令名为
    VMULL.P8
    8位x 8位->16位
    )。在ARMv8中,该指令称为
    PMUL
    /
    PMULL
    /
    PMULL2
    。带加密扩展的ARMv8除了支持ARMv7变体外,还支持
    64位x 64位->128位
    无载频乘法。谢谢,我认为这是有意义的:D
    poly8x16\u t vmulq\u p8(poly8x16\u t,poly8x16\u t)
    给出预期指令的形式:vmul.p8 q0,q0,q0。如果它是
    vmul.p8
    ,它的意思是GF(2^8),但您的解释是GF(2)?也就是说,第八位没有进位,但中间有进位。GF(2)乘法是
    XOR/EOR
    ,GF(2)乘法是AND运算;GF(2)及其扩展中的加法是XOR。多项式乘法使用XOR对行进行求和,而常规二进制乘法使用ADD。(在ADD中,所有位之间可能存在进位)。我还没有检查文档,但我相信vmul.p8只会占用carryless产品的8个最低有效位;而vmull.p8将从p8*p8->p16生成完整的产品。是的,我想的是
    vmull
    和GF(256)而不是GF(2^8)。
     1101 == x^3 + x^2 + 0 + 1;
     1001 == x^3 + 0   + 0 + 1;
    
     (x^3 + x^2 + 1)(x^3 + 1) == x^6+x^5+x^3 + x^3+x^2+1 
                              == 1x^6 + 1x^5 + 0x^4 + 2x^3 + 1^x2 + 0x + 1
                              == "1102101"