Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly xmm寄存器的乘法_Assembly_X86_Simd - Fatal编程技术网

Assembly xmm寄存器的乘法

Assembly xmm寄存器的乘法,assembly,x86,simd,Assembly,X86,Simd,我对汇编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:

我对汇编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

> P> >简化的C++,它只需遍历矩阵的所有元素,因为这就是您的<代码> [ i,j] < /COD>嵌套循环。您不需要计算
i*M+j
,因为您的公式不以任何特定方式使用i/j,它只需遍历所有元素一次:

void muldata(float* fxx, const float* fx, const float* fy, const unsigned int M, const unsigned int N) {
    int ofs = 0;
    do {
        fxx[ofs] = fx[ofs] * fy[ofs];
        ++ofs;
    } while (ofs < M*N);
}
这远远优于您的代码(默认情况下包括循环的矢量化)

若您指定指针的对齐方式并使M/N编译时为常量,它可能会产生更好的结果


<>我刚刚通过Cpp.SH站点验证了C++变体作品,并将其扩展到:

#include <iostream>

void muldata(float* fxx, const float* fx, const float* fy, const unsigned int M, const unsigned int N) {
    unsigned int ofs = 0;
    do {
        fxx[ofs] = fx[ofs] * fy[ofs];
        ++ofs;
    } while (ofs < M*N);
}

int main()
{
    // constexpr unsigned int M = 1;
    // constexpr unsigned int N = 1;
    // const float fx[M*N] = { 2.2f };
    // const float fy[M*N] = { 3.3f };

    constexpr unsigned int M = 3;
    constexpr unsigned int N = 2;
    const float fx[M*N] = { 2.2f, 1.0f, 0.0f,
                            1.0f, 1.0f, 1e-24f };
    const float fy[M*N] = { 3.3f, 3.3f, 3.3f,
                            5.5f, 1e30f, 1e-24f };

    float fr[M*N];
    muldata(fr, fx, fy, M, N);
    for (unsigned int i = 0; i < N; ++i) {
        for (unsigned int j = 0; j < M; ++j) std::cout << fr[i*M+j] << " ";
        std::cout << std::endl;
    }
}

还有注释掉的1x1输入数据,这应该是在您的情况下调试的第一件事。试着让这个例子在你最喜欢的C++ IDE中运行,然后用汇编代码替换<代码> MulDATA<代码>,并通过它调试,看看它是在哪里运行的。

< P>问题解决了。问题是,我从C传递了一个int矩阵。相反,如果我传递了一个float矩阵,代码就会工作。

如果
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%的软件在这种机器上会出现故障。问题在于代码和/或数据,而不是指令,指令工作正常。您没有提供任何特定的测试用例(包括输入数据、预期输出数据和实际输出数据)。我尝试了我的C++下面的答案,通过CPP.SH在线网站,它工作如预期,我将更新答案与完整的工作示例。问题解决。问题是我从C传递了一个int矩阵。相反,如果我传递了一个float矩阵,代码就可以工作了。谢谢大家。对不起,我是新来的
#include <iostream>

void muldata(float* fxx, const float* fx, const float* fy, const unsigned int M, const unsigned int N) {
    unsigned int ofs = 0;
    do {
        fxx[ofs] = fx[ofs] * fy[ofs];
        ++ofs;
    } while (ofs < M*N);
}

int main()
{
    // constexpr unsigned int M = 1;
    // constexpr unsigned int N = 1;
    // const float fx[M*N] = { 2.2f };
    // const float fy[M*N] = { 3.3f };

    constexpr unsigned int M = 3;
    constexpr unsigned int N = 2;
    const float fx[M*N] = { 2.2f, 1.0f, 0.0f,
                            1.0f, 1.0f, 1e-24f };
    const float fy[M*N] = { 3.3f, 3.3f, 3.3f,
                            5.5f, 1e30f, 1e-24f };

    float fr[M*N];
    muldata(fr, fx, fy, M, N);
    for (unsigned int i = 0; i < N; ++i) {
        for (unsigned int j = 0; j < M; ++j) std::cout << fr[i*M+j] << " ";
        std::cout << std::endl;
    }
}
7.26 3.3 0 
5.5 1e+30 0