gpt4 book ai didi

assembly - 为什么 FMA _mm256_fmadd_pd() 内在函数有 3 个 asm 助记符, "vfmadd132pd"、 "231"和 "213"?

转载 作者:行者123 更新时间:2023-12-03 23:35:15 26 4
gpt4 key购买 nike

有人可以向我解释为什么融合乘法累加指令有 3 种变体:vfmadd132pd , vfmadd231pdvfmadd213pd ,而只有一个 C 内在函数 _mm256_fmadd_pd ?

为了简单起见,(在 AT&T 语法中)有什么区别

vfmadd132pd  %ymm0, %ymm1, %ymm2
vfmadd231pd %ymm0, %ymm1, %ymm2
vfmadd213pd %ymm0, %ymm1, %ymm2

我没有从 Intel's intrinsics guide 得到任何想法.我问是因为我在我编写的一段 C 代码的汇编输出中看到了所有这些。谢谢。

一个干净的答案(在下面重新格式化答案)

对于变体 ijkvfmaddijkpd的含义:
  • 英特尔语法:op(i) * op(j) + op(k) -> op(1)
  • AT&T 语法:op(4-i) * op(4-j) + op(4-k) -> op(3)

  • 哪里 op(n)表示指令后的第 n 个操作数。所以有一个 反向 两者之间的转换:
    n <- 4 - n

    最佳答案

    融合乘加指令将两个(压缩)值相乘,添加第三个值,然后用结果覆盖其中一个值。这三个值中只有一个可以是内存操作数而不是寄存器。

    它的工作方式是所有三个指令都覆盖 ymm0并且只允许 ymm2成为内存操作数。指令的选择决定了哪两个操作数相乘,哪一个相加。

    假设 ymm0 是 Intel 语法中的第一个操作数(或 AT&T 语法中的最后一个):

    vfmadd132pd:  ymm0 = ymm0 * ymm2/mem + ymm1
    vfmadd231pd: ymm0 = ymm1 * ymm2/mem + ymm0
    vfmadd213pd: ymm0 = ymm1 * ymm0 + ymm2/mem

    使用 C 内在函数时,此选择不是必需的:内在函数不会覆盖值而是返回其结果,并且允许从内存中读取所有三个值。如果需要,编译器将添加内存读/写,如果不希望三个值中的任何一个被覆盖,它将分配一个临时寄存器来存储结果。它将选择它认为合适的三个指令之一。

    关于assembly - 为什么 FMA _mm256_fmadd_pd() 内在函数有 3 个 asm 助记符, "vfmadd132pd"、 "231"和 "213"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36391719/

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