- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有三个 ymm 寄存器 - ymm4、ymm5 和 ymm6 - 包含 double (qword) float :
ymm4: 73 144 168 41
ymm5: 144 348 26 144
ymm6: 732 83 144 852
我想写出上面矩阵的每一列。例如:
-- extract ymm4[63:0] and insert it at ymm0[63:0]
-- extract ymm5[63:0] and insert it at ymm0[127:64]
-- extract ymm6[63:0] and insert it at ymm0[191:128]
这样 ymm0 就会读取 73, 144, 732。
到目前为止我已经使用过:
mov rax,4
kmovq k6,rax
vpxor ymm1,ymm1
VEXPANDPD ymm1{k6}{z},ymm6
这会导致 ymm1 读取 [ 0 0 732 ],因此我已经完成了第一步,因为 732 是 ymm6 中 [63:0] 处的元素。
对于 ymm4 和 ymm5,我使用 vblendpd:
vblendpd ymm0,ymm1,ymm4,1
这会导致 ymm0 读取 [ 73 0 732 ],因此我完成了第二步,因为 73 是 ymm4 中 [63:0] 处的元素。
现在我需要将 ymm5[63:0] 放在 ymm0[127:64] 处:
vblendpd ymm0,ymm0,ymm5,2
这会导致 ymm0 读取 [ 73 144 732 ],所以现在我完成了第一列 [63:0]。
但现在我需要对 ymm 寄存器中的第 2、3 和 4 列执行相同的操作。在添加更多说明之前,这是执行我所描述的操作的最有效方法吗?还有其他更有效的方法吗?
我已经研究了 unpckhpd ( https://www.felixcloutier.com/x86/unpckhpd )、vblendpd ( https://www.felixcloutier.com/x86/blendpd 和 vshufpd ( https://www.felixcloutier.com/x86/shufpd ),上面显示的似乎是最好的解决方案,但它有很多指令,并且编码显示在imm8 值的文档有些不透明。是否有更好的方法来提取三个 ymm 寄存器的相应列?
最佳答案
让我们这样命名矩阵元素:
YMM0 = [A,B,C,D]
YMM1 = [E,F,G,H]
YMM2 = [I,J,K,L]
最终,您想要这样的结果,其中 *
表示“不关心”。
YMM0 = [A,E,I,*]
YMM1 = [B,F,J,*]
YMM2 = [C,G,K,*]
YMM3 = [D,H,K,*]
为了实现这一点,我们将矩阵扩展到 4×4(想象另一行只有 [*,*,*,*]
),然后转置矩阵。这分两步完成:首先,对每个 2×2 子矩阵进行转置。然后,交换左上角和右下角的矩阵:
[A,B,C,D] [A,E,C,G] [A,E,I,*]
[E,F,G,H] --\ [B,F,D,H] --\ [B,F,J,*]
[I,J,K,L] --/ [I,*,K,*] --/ [C,G,K,*]
[*,*,*,*] [J,*,L,*] [D,H,L,*]
对于 ymm0
和 ymm1
中的第一步,我们使用一对解包指令:
vunpcklpd %ymm1, %ymm0, %ymm4 // YMM4 = [A,E,C,G]
vunpckhpd %ymm1, %ymm0, %ymm5 // YMM5 = [B,F,D,H]
第 3 行暂时保留在 ymm2
中,因为不需要更改。第 4 行是通过将 ymm2
与其自身解压得到的:
vunpckhpd %ymm2, %ymm2, %ymm6 // YMM5 = [J,*,L,*]
第二步是通过混合和交换车道两次来实现的:
vblendpd $0xa, %ymm2, %ymm4, %ymm0 // YMM0 = [A,E,I,*]
vblendpd $0xa, %ymm6, %ymm5, %ymm1 // YMM1 = [B,F,J,*]
vperm2f128 $0x31, %ymm2, %ymm4, %ymm2 // YMM2 = [C,G,K,*]
vperm2f128 $0x31, %ymm6, %ymm5, %ymm3 // YMM3 = [D,H,L,*]
这用 7 条指令实现了所需的排列。
请注意,由于这些指令都不需要 AVX2,因此该代码将在仅具有 AVX 的 Sandy Bridge 处理器上运行。
关于assembly - 是否有更好的 AVX 指令来从 3 ymm 寄存器移动数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63782703/
是否存在任何 SIMD/向量寄存器指令,其中 ymm 寄存器是在通用寄存器(或 SIMD 寄存器)中指定的,而不是在指令本身中指定的? 本质上,我想做的是编写一个函数,将任何一系列连续的 ymm 寄存
从 SIMD 寄存器加载和存储生成用途寄存器的最佳方式是什么?到目前为止,我一直使用堆栈作为临时的。例如, mov [rsp + 0x00], r8 mov [rsp + 0x08], r9 mov
考虑: movdqa xmm0, xmmword ptr [rcx] movdqa xmm1, xmmword ptr [rcx + 16] movdqa xmm2, xmmword ptr [rcx
幸运的是,PTEST 不会影响进位标志,而只会设置(相当尴尬的)ZF。还会影响 CF 和 ZF。 我提出了以下序列来测试大量值,但我对糟糕的运行时间感到不满意。 Laten
考虑: movdqa xmm0, xmmword ptr [rcx] movdqa xmm1, xmmword ptr [rcx + 16] movdqa xmm2, xmmword ptr [rcx
如何在最少的时钟周期内将 YMM 寄存器的最低 64 位设置为某个常数?我知道可以使用 SSE 指令以及 AVX 指令 VBROADCASTSD 执行此操作的各种方法,但我不确定哪种方法会产生最佳结果
我想在 gcc(AT&T 语法)中运行以下代码(Intel 语法)。 ; float a[128], b[128], c[128]; ; for (int i = 0; i : vmovaps -
这个问题适用于 Haswell 上带有 XMM/YMM 寄存器的打包、单精度浮点运算。 所以根据真棒,真棒table由 Agner Fog 汇总,我知道 MUL 可以在端口 p0 和 p1 上完成(r
伙计们,假设我有一个模板函数: template Vector* Vector::overwrite(const Vector* copy) { this->_normalized = co
我有 2 个变量来模拟 X86 XMM 和 YMM,如下所示: uint64_t xmm_value[2]; uint64_t ymm_value[4]; 现在我想使用内联汇编来读写 XMM/YMM
考虑 x86 中的以下循环: ; on entry, rdi has the number of iterations .top: ; some magic happens here to calcu
我有三个 ymm 寄存器 - ymm4、ymm5 和 ymm6 - 包含 double (qword) float : ymm4: 73 144 168 41 ymm5: 144 348 2
我有三个 ymm 寄存器 - ymm4、ymm5 和 ymm6 - 包含 double (qword) float : ymm4: 73 144 168 41 ymm5: 144 348 2
我正在使用英特尔 AVX 内在函数实现粒子系统。当粒子的 Y 位置小于或等于零时,我想重置粒子。 粒子系统按照这样的 SOA 模式排序: class ParticleSystem { priv
如何将单个 32 位浮点加载/转换为 AVX 256 ymm 寄存器,以便所有 8 个 float 都来自单个源 float ? 之前我使用 AVX 128 xmm 寄存器将单个 float 加载到
好像是recurring problem许多英特尔处理器(直到 Skylake,除非我错了)在将 AVX-256 指令与 SSE 指令混合时表现出较差的性能。 根据 Intel's documenta
我有一个 x86_64 例程,如果成功,它最终在 YMM 寄存器中以零结束,如果 YMM 寄存器,我想返回非零值。 我有一种方法可以通过清除另一个 YMM 寄存器,针对那个寄存器对我的寄存器进行 VP
xmm有什么区别和 ymm注册? 我以为xmm用于 SSE,和 ymm用于 AVX,但我写了一些代码: vmovups ymm1, [r9] vcvtss2si rcx, ymm
有什么办法可以交换 256 位 AVX(YMM) 寄存器中的中间两个 64 位吗? 我知道我们可以利用 VPERM2F128 来交换低 128 位和高 128 位,而 vshufps 似乎只能在高 1
几乎就像标题所说的那样,我需要一种方法来将 256-avx-register 寄存器中所有元素的位置移动/混洗 N 个位置。我发现的所有关于此的使用 32 或 64 位值(__builtin_ia32
我是一名优秀的程序员,十分优秀!