C++ 如何将%rax中的双精度移动到%ymm或%zmm上的特定qword位置?(卡比湖或更高版本)
我的想法是,我希望一次收集C++ 如何将%rax中的双精度移动到%ymm或%zmm上的特定qword位置?(卡比湖或更高版本),c++,x86-64,inline-assembly,intrinsics,avx,C++,X86 64,Inline Assembly,Intrinsics,Avx,我的想法是,我希望一次收集double的返回值到一个向量寄存器中,以便对机器imm width进行处理,而不首先将存储回内存 特定的处理是一个vfma,另外两个操作数都是constepr,因此它们可以通过\u mm256\u setr\u pd调用,或者从constepr数组中对齐/未对齐的内存加载 有没有办法直接从%rax中的值将双精度存储在%ymm中的特定位置,以便收集 目标机器是卡比湖。更高效的未来向量指令也受欢迎。内联汇编通常是个坏主意:现代编译器在x86内部函数方面做得很好 将doub
double
的返回值到一个向量寄存器中,以便对机器imm width
进行处理,而不首先将存储回内存
特定的处理是一个vfma
,另外两个操作数都是constepr
,因此它们可以通过\u mm256\u setr\u pd
调用,或者从constepr
数组中对齐/未对齐的内存加载
有没有办法直接从%rax
中的值将双精度存储在%ymm
中的特定位置,以便收集
目标机器是卡比湖。更高效的未来向量指令也受欢迎。内联汇编通常是个坏主意:现代编译器在x86内部函数方面做得很好
将double
的位模式放入RAX通常也没用,而且闻起来你可能已经走错了路,进入了次优领域。矢量洗牌指令通常更好:在英特尔硬件上,按元素插入/提取指令已经花费了洗牌uop,除了vmovq%xmm0,%rax
以获得低位元素
此外,如果要将其插入到另一个向量中,则应使用shuffle/immediate blend。(vpermpd
/vblendpd
)
L1d和存储转发缓存速度很快,即使存储转发暂停也不是灾难。在ALU和内存之间进行明智的选择,以将数据收集或分散到SIMD向量中。还要记住,插入/提取指令需要一个即时索引,所以如果您有一个向量的运行时索引,那么您肯定要存储它和索引。(请参阅中的和其他性能链接)
在Haswell和更高版本上,大量的插入/提取可能会很快导致端口5出现瓶颈有关更多详细信息,请参见,以及gcc错误报告的一些链接,在这些报告中,我详细介绍了不同UARCHE上不同元素宽度的策略以及使用SSE4.1与不使用SSE4.1的策略等
没有PD版本,并且insertps
是XMM向量之间的混洗
要读取/写入YMM的低端通道,必须使用integervpextrq$1、%xmm0、%rax
/pinsrq$1、%rax、%xmm0
。这些在YMM宽度中不可用,因此您需要多条指令来读取/写入高速通道
VEX版本vpinsrq$1、%rax、%xmm0
将使目标向量的全YMM或ZMM宽度的高端车道归零,这就是我建议pinsrq
的原因。在Skylake和更高版本上,它不会导致SSE/AVX转换暂停。请参阅以获取示例(NASM语法),以及
对于低端元素,使用vmovq%xmm0,%rax
提取,它比vpextrq
便宜(1个计量单位而不是2个计量单位)
对于ZMM,我对链接的XMM from GP regs问题的回答表明,给定一个具有单个位集的掩码寄存器,您可以使用AVX512F将掩码整数寄存器合并到向量中
vpbroadcastq %rax, %zmm0{%k1}
类似地,vpcompressq
可以将由单个位掩码选择的元素移动到vmovq
的底部
但是对于提取,如果使用索引而不是1内联汇编通常是个坏主意:现代编译器在x86内部函数方面做得很好
将double
的位模式放入RAX通常也没用,而且闻起来你可能已经走错了路,进入了次优领域。矢量洗牌指令通常更好:在英特尔硬件上,按元素插入/提取指令已经花费了洗牌uop,除了vmovq%xmm0,%rax
以获得低位元素
此外,如果要将其插入到另一个向量中,则应使用shuffle/immediate blend。(vpermpd
/vblendpd
)
L1d和存储转发缓存速度很快,即使存储转发暂停也不是灾难。在ALU和内存之间进行明智的选择,以将数据收集或分散到SIMD向量中。还要记住,插入/提取指令需要一个即时索引,所以如果您有一个向量的运行时索引,那么您肯定要存储它和索引。(请参阅中的和其他性能链接)
在Haswell和更高版本上,大量的插入/提取可能会很快导致端口5出现瓶颈有关更多详细信息,请参见,以及gcc错误报告的一些链接,在这些报告中,我详细介绍了不同UARCHE上不同元素宽度的策略以及使用SSE4.1与不使用SSE4.1的策略等
没有PD版本,并且insertps
是XMM向量之间的混洗
要读取/写入YMM的低端通道,必须使用integervpextrq$1、%xmm0、%rax
/pinsrq$1、%rax、%xmm0
。这些在YMM宽度中不可用,因此您需要多条指令来读取/写入高速通道
VEX版本vpinsrq$1、%rax、%xmm0
将使目标向量的全YMM或ZMM宽度的高端车道归零,这就是我建议pinsrq
的原因。在Skylake和更高版本上,它不会导致SSE/AVX转换暂停。请参阅以获取示例(NASM语法),以及
对于低端元素,使用vmovq%xmm0,%rax
提取,它比vpextrq
便宜(1个计量单位而不是2个计量单位)
对于ZMM,我对链接的XMM from GP regs问题的回答表明,给定一个具有单个位集的掩码寄存器,您可以使用AVX512F将掩码整数寄存器合并到向量中
vpbroadcastq %rax, %zmm0{%k1}
类似地,vpcompressq
可以将由单个位掩码选择的元素移动到vmovq
的底部
但对于提取,如果有索引而不是1