gpt4 book ai didi

assembly - 128位至512位寄存器有什么用?

转载 作者:行者123 更新时间:2023-12-04 10:22:52 29 4
gpt4 key购买 nike

在查看了x86/x64体系结构中的寄存器表之后,我注意到有完整的128位,256位和512位寄存器部分,我从未见过它们在汇编或反编译的C/C++代码中使用: XMM(0-15)代表128,YMM(0-15)代表256,ZMM(0-31)512。

在做了一点挖掘之后,我必须使用2个64位运算来对128位数字进行数学运算,而不是使用通用的addsubmuldiv运算。如果是这种情况,那么拥有这些扩展的寄存器集到底有什么用,并且可以使用任何汇编操作来对其进行操作?

最佳答案

这些用于

  • 浮点运算
  • 一次对多个数据进行操作

  • you have to use 2 64 bit operations in order to perform math on a 128 bit number



    不,它们不是用于此目的的,您不能轻松地将它们用于128位数字。仅用2条指令添加128位数字的速度要快得多:如果处理XMM寄存器,则使用 add rax, rbx; adc rdx, rcx 而不是大量指令。看
  • practical BigNum AVX/SSE possible?
  • Is it possible to use SSE (v2) to make a 128-bit wide integer?


  • 关于它们的用法,首先将它们用于 标量浮点运算。因此,如果您在C或C++中具有 floatdouble,则很可能将它们存储在XMM寄存器的下部,并通过以 ss(标量单)或 sd(标量双)结尾的指令进行操作

    实际上,还有另一组八个80位 ST(x)寄存器,可与 x87 co-processor一起使用来进行浮点数学运算。但是,它们速度慢且难以预测。速度慢,因为默认情况下操作会以更高的精度进行,这固有地需要更多的工作,并且在必要时还需要 requires a store then load to round to lower precision。高精度也是不可预测的。乍一看这很奇怪,但是很容易解释,例如某些操作在 floatdouble精度上上溢或下溢,但在 long double精度上不上。这会导致32和64位build1中的许多错误或意外结果

    Here is a floating-point example on both sets of registers
    // f = x/z + y*z
    x87:
    fld dword ptr [esp + 12]
    fld st(0)
    fdivr dword ptr [esp + 4]
    fxch st(1)
    fmul dword ptr [esp + 8]
    faddp st(1)
    ret
    SSE:
    divss xmm0, xmm2
    mulss xmm1, xmm2
    addss xmm0, xmm1
    ret
    AVX:
    vdivss xmm0, xmm0, xmm2
    vmulss xmm1, xmm1, xmm2
    vaddss xmm0, xmm0, xmm1
    ret

    转向更快,更一致的SSE寄存器是 the 80-bit extended precision long double type is not available in MSVC anymore的原因之一

    然后,英特尔为 MMX instruction set操作引入了 SIMD,该操作使用具有新名称 ST(x)的相同 MMX寄存器。 MMX可能代表Multiple Math eXtension或Matrix Math eXtension,但是恕我直言,它很可能是MultiMedia eXtension,因为多媒体和互联网在当时变得越来越重要。在多媒体解决方案中,您经常必须对每个像素,纹理像素,声音样本执行相同的操作……
    for (int i = 0; i < 100000; ++i)
    {
    A[i] = B[i] + C[i];
    D[i] = E[i] * F[i];
    }

    无需单独对每个元素进行操作,我们可以一次执行多个元素来加快速度。这就是人们发明SIMD的原因。使用MMX,您可以一次增加8个像素 channel 的亮度,或者一次增加四个16位声音样本的音量...单个元素上的操作称为 scalar,完整寄存器称为矢量,它是一组标量值(value)观

    由于MMX的缺点(例如重用 ST寄存器或缺少浮点支持),当使用 Streaming SIMD Extensions (SSE)扩展SIMD指令集时,英特尔决定为它们提供一套全新的名为XMM的寄存器,该寄存器集的长度是原来的两倍(128位) ),因此我们现在可以一次处理16个字节。而且它还一次支持多个浮点运算。然后,Intel在 Advanced Vector Extensions (AVX)中将XMM扩展为256位YMM,并在 AVX-512中将其长度再次加倍(这也使寄存器的数量在64位模式下增加到32个)。现在您可以一次处理 十六个32位整数

    通过上面的内容,您可能会了解这些寄存器的第二个也是最重要的角色: 与单个指令并行执行多个数据的操作。例如,在 SSE4中引入了一组 instructions to work on C strings。现在您可以计算字符串长度,查找子字符串...通过一次检查多个字节来更快。您还可以更快地复制或比较内存。现代 memcpy实现一次最多可移动16、32或64个字节,具体取决于最大的寄存器宽度,而不是像最简单的C解决方案那样一一对应。

    不幸的是,尽管自动矢量化仍在变得越来越智能,但编译器仍然无法从标量代码转换为并行代码,因此大多数时候我们都必须提供帮助。
  • Automatic vectorization
  • Auto-Parallelization and Auto-Vectorization

  • 由于SIMD的重要性,当今几乎所有高性能架构都具有自己的SIMD版本,例如PowerPC上的 Altivec或ARM上的 Neon

    1一些例子:
  • Is SSE floating-point arithmetic reproducible?
  • Extended (80-bit) double floating point in x87, not SSE2 - we don't miss it?
  • acos(double) gives different result on x64 and x32 Visual Studio
  • Why would the same code yield different numeric results on 32 vs 64-bit machines?
  • Difference in floating point arithmetics between x86 and x64
  • std::pow produce different result in 32 bit and 64 bit application
  • Why does Math.Exp give different results between 32-bit and 64-bit, with same input, same hardware
  • 关于assembly - 128位至512位寄存器有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52932539/

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