我想将此代码从NASM 32位SSE转换为NASM 64-AVX。有可能找到一种方便的方法吗?
为了转换为64位代码,我会尝试完全重写32位代码。但是,我认为这是非常艰苦的工作,我认为有一种几乎自动的方式来做所有事情。
你知道这样的过程吗?例如,替换寄存器的名称?
示例:
eax
更改为rax
,将ebx
更改为rbx
,依此类推...... movaps
更改vmovaps
,依此类推...... 这是我的32位NASM源代码:
section .text
global test
a equ 8
b equ 12
num equ 16
spuri equ 20
result equ 24
test:
push ebp
mov ebp, esp
push ebx
push esi
push edi
mov esi, [ebp+a]
mov edi, [ebp+b]
mov ebx, 0
mov ecx, [ebp+num]
mov edx, [ebp+spuri]
mov eax,[ebp+result]
xorps xmm1,xmm1
xorps xmm3,xmm3
loop1:
cmp ecx,0
je end
movups xmm0, [esi+ebx]
movups xmm6, [edi+ebx]
subps xmm0, xmm6
mulps xmm0, xmm0
sqrtps xmm0, xmm0
addps xmm1, xmm0
add ebx, 16
dec ecx
jnz loop1
end:
haddps xmm1,xmm1
haddps xmm1,xmm1
addps xmm1,xmm3
movups [eax],xmm1
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
我试图转换此代码但没有任何好结果。
答案 0 :(得分:1)
将32位移植到64位是从SSE移植到256b AVX的正交。但是,同时执行这两个操作意味着您只需要遍历代码的每一行,而不是每个任务执行一次。
SSE-> AVX:如果你有任何改组或任何东西,这很棘手,因为现有SSE指令的AVX版本基本上在两个“通道”中执行两个独立的128b操作。
32-> 64b:就arg传递而言,ABI是不同的,你需要保存/恢复。指针通常需要进入64b寄存器,但尽可能使用32位寄存器。写入32位寄存器零 - 扩展到完整的64b寄存器,因此您仍然使用xor eax,eax
将寄存器归零。 xor rax,rax
浪费了一个指令字节。如果您不打算关注此级别的优化,只需将其写入C。
对静态/全局数据使用RIP相对寻址。
请参阅x86代码Wiki以获取链接。
如果你没有比编写mulps xmm0, xmm0
/ sqrtps xmm0, xmm0
的人更好的asm,那么放弃ASM并用C重写你的代码。你最大的加速将来自{{ 3}}在你现有的代码库中,甚至超过了矢量宽度加倍的潜在因子2加速。
如今,任何优秀的优化编译器都能很好地自动矢量化许多简单的标量循环。使用最新版本的gcc或clang。
您也可以使用fixing stuff like that,因此您可以使用相同的手动矢量化构建32或64位可执行文件。