【发布时间】:2019-12-10 07:08:22
【问题描述】:
我有 2 个变量来模拟 X86 XMM 和 YMM,如下所示:
uint64_t xmm_value[2];
uint64_t ymm_value[4];
现在我想使用内联汇编来读写 XMM/YMM 寄存器。
- 如何编写GCC内联汇编复制
xmm_value到注册XMM0? - 如何编写 GCC 内联汇编将寄存器
YMM0复制到ymm_value?
我已经尝试搜索执行此操作的示例内联汇编,但找不到任何好的答案。谢谢!
在一些帮助下,我编写了这段代码,并且编译成功。我对 XMM 使用 movups,对 YMM 使用 vmovups,如下所示。这是正确的,我还能优化我的代码吗?
__m128 xmm0;
__m256 ymm0;
// write to XMM0, and read from YMM0
__asm__("movups %1, %%xmm0\n\t"
"vmovups %%ymm0, %0"
: "=m"(ymm0)
: "m"(xmm0)
: "xmm0", "ymm0");
更新 2:这是我的完整代码(添加了 vpbroadcastb)
__m128 xmm0;
__m256 ymm0;
// write to XMM0, and read from YMM0
__asm__("movups %1, %%xmm0\n\t"
"vpbroadcastb %%xmm0, %%ymm0\n\t"
"vmovups %%ymm0, %0"
: "=m"(ymm0)
: "m"(xmm0)
: "xmm0", "ymm0");
想法是我想将xmm0(变量)复制到XMM0,然后运行vpbroadcastb,然后将YMM0中的结果复制到ymm0(变量)。现在才知道XMM0是YMM0的下半部分,所以这段代码还可以改进吗?
【问题讨论】:
-
为什么需要为此使用内联汇编?
-
感谢您的指点,但这些链接并没有直接回答我的问题,所以我认为其他人仍然可以从这个问题中受益。
-
为什么要使用内存操作数而不是 XMM 寄存器?此外,您可能希望将
vmovups %1, %%xmm0零扩展到 YMM0(就像将 EAX 隐式零扩展到 RAX 一样)。使用旧版 SSE 指令写入 XMM0 会使上层通道保持不变。另请参阅 Why is this SSE code 6 times slower without VZEROUPPER on Skylake? 以了解 XMM 错误依赖项或 SSE/AVX 转换停止。 (这不会导致 Haswell 上的转换停顿,除非有任何 YMM 寄存器带有脏上限,但混合 SSE 和 AVX 需要小心)
标签: gcc assembly sse inline-assembly