【发布时间】:2017-10-29 22:52:09
【问题描述】:
我在汇编 sse 中的两个寄存器相乘时遇到问题。 这是我的代码:
moltiplicazionePuntoPunto:
mov edx,[esp+20] ; edx = fxx
mov esi,[esp+4] ; esi = fx
mov edi,[esp+8] ; edi = fy
xor eax,eax ; i=0
fori: cmp eax,[esp+12] ; confronta i con N
jge endfori
xor ebx,ebx ; j=0
forj: cmp ebx,[esp+16] ; confronta j con M
jge endforj
mov ecx,eax
imul ecx,[esp+16] ; ecx = i*M
add ecx,ebx ; ecx = i*M+j
movss xmm5,[esi+ecx*4] ; xmm5 = fx[i*M+j]
movss xmm6,[edi+ecx*4] ; xmm6 = fy[i*M+j]
mulps xmm5,xmm6 ; xmm7 = fx[i*M+j]*fx[i*M+j]
movss [edx+ecx*4],xmm5 ; fxx[i*M+j] = fx*fx
inc ebx
jmp forj
endforj:
inc eax
jmp fori
endfori:
此代码修改矩阵 fxx,其中元素 fxx[i*M+j] = fx[i*M+j] * fy[i*M+j]。问题是当我执行mulps xmm5,xmm6 操作时,结果为0。
【问题讨论】:
-
如果
mulps xmm5,xmm6为零,则xmm5或xmm6之一为零。那么它是哪一个呢?你为什么不使用例如 C++,它肯定会产生更快的循环,至少它会优化i*M等......而且它可能更容易调试和维护。 -
其实当然还有其他的极端情况,float x * float y = 0,即使x/y都是非零,因为float本身精度有限,比如
1e-23 * 1e-23 = 0等等......如果没有来自调试器的一些示例数据,就不可能知道你遇到了什么,如果你看到数据,你可能也看到了答案。 -
我认为问题在于 mulps 指令而不是寄存器的值。因为如果我用 istruction addps 更改 istruction mulps 代码就可以工作
-
就像你的 CPU 坏了,
mulps没有做它应该做的,对吧?使用常识,90% 的软件在这种机器上都会失败。问题出在您的代码和/或数据中,而不是指令中,指令正常工作。您没有提供任何特定的测试用例(minimal reproducible example 包括输入数据、预期输出数据和实际输出数据)。我在下面通过 cpp.sh 在线站点的答案尝试了我的 C++,它按预期工作,我将使用完整的示例更新答案。 -
问题已解决。问题是我从 C 传递了一个 int 矩阵。相反,如果我传递一个浮点矩阵,代码就可以工作。谢谢大家。抱歉,我是组装新手