gpt4 book ai didi

assembly - 将常量 float 加载到 SSE 寄存器中

转载 作者:行者123 更新时间:2023-12-02 08:07:37 24 4
gpt4 key购买 nike

我正在尝试找出一种有效的方法来将编译时常量 float 加载到 SSE(2/3) 寄存器中。我尝试过编写这样的简单代码,

const __m128 x = { 1.0f, 2.0f, 3.0f, 4.0f }; 

但这会从内存中生成 4 条 movss 指令!

movss       xmm0,dword ptr [__real@3f800000 (14048E534h)] 
movss xmm1,dword ptr [__real@40000000 (14048E530h)]
movaps xmm6,xmm12
shufps xmm6,xmm12,0C6h
movss dword ptr [rsp],xmm0
movss xmm0,dword ptr [__real@40400000 (14048E52Ch)]
movss dword ptr [rsp+4],xmm1
movss xmm1,dword ptr [__real@40a00000 (14048E528h)]

它将标量加载到内存中或从内存中加载出来......(?!?!)

尽管这样做..

float Align(16) myfloat4[4] = { 1.0f, 2.0f, 3.0f, 4.0f, }; // out in global scope

生成。

movaps      xmm5,xmmword ptr [::myarray4 (140512050h)]

理想情况下,如果我有常量,那就太好了,这将是一种甚至不接触内存而只需使用立即样式指令(例如编译到指令本身中的常量)来完成的方法。

谢谢

最佳答案

如果你想强制它加载一次,你可以尝试(gcc):

__attribute__((aligned(16))) float vec[4] = { 1.0f, 1.1f, 1.2f, 1.3f };
__m128 v = _mm_load_ps(vec); // edit by sor: removed the "&" cause its already an address

如果您有 Visual C++,请使用 __declspec(align(16))请求适当的约束。

在我的系统上,这个(用 gcc -m32 -msse -O2 编译;没有任何优化会使代码困惑,但最终仍然保留单个 movaps)创建以下汇编代码(gcc/AT&T 语法):

    andl    $-16, %esp
subl $16, %esp
movl $0x3f800000, (%esp)
movl $0x3f8ccccd, 4(%esp)
movl $0x3f99999a, 8(%esp)
movl $0x3fa66666, 12(%esp)
movaps (%esp), %xmm0

请注意,它会在分配堆栈空间并将常量放入其中之前对齐堆栈指针。离开__attribute__((aligned)) out 可能会根据您的编译器创建不执行此操作的错误代码,因此请小心并检查反汇编。

另外:
既然您一直在询问如何将常量放入代码中,只需使用 static 尝试上述操作即可。 float 的限定符大批。这将创建以下程序集:

    movaps  vec.7330, %xmm0
...
vec.7330:
.long 1065353216
.long 1066192077
.long 1067030938
.long 1067869798

关于assembly - 将常量 float 加载到 SSE 寄存器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5007885/

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