Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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
C 如何使用SSE汇编指令查找毕达哥拉斯三元组?_C_Assembly_Sse - Fatal编程技术网

C 如何使用SSE汇编指令查找毕达哥拉斯三元组?

C 如何使用SSE汇编指令查找毕达哥拉斯三元组?,c,assembly,sse,C,Assembly,Sse,我对汇编非常陌生,我想找到所有毕达哥拉斯三元组,范围从1到100。我用C生成所有的数字,所有其他的计算都应该用汇编语言完成。我试图通过使用sqrt命令来实现这一点(我已经尝试了所有这些命令),但我无法使其工作。。 有人能告诉我应该怎么做吗 这就是我到目前为止得到的: int main(){ for (int i = 1; i <= 100; i++) { a++; if (a &

我对汇编非常陌生,我想找到所有毕达哥拉斯三元组,范围从1到100。我用C生成所有的数字,所有其他的计算都应该用汇编语言完成。我试图通过使用sqrt命令来实现这一点(我已经尝试了所有这些命令),但我无法使其工作。。 有人能告诉我应该怎么做吗

这就是我到目前为止得到的:

int main(){
            for (int i = 1; i <= 100; i++)
            {
                a++;
                if (a > 100)
                    a = 0;
                for (int j = 1; j <= 100; j++)
                {
                    b++;
                    if (b > 100)
                        b = a;
                    _asm   //tricky part begins here:
                    {
                        movups xmm0, a
                        movups xmm1, b
                        pmuludq xmm0, xmm0  
                        pmuludq xmm1, xmm1 
                        //movups xmm2, 0  
                        //paddd xmm2, xmm0  
                        //paddd xmm2, xmm1
                        movups z, xmm0
                    }
                    printf("%d\n", z);
                }
          }
    }
intmain(){
对于(int i=1;i 100)
a=0;
对于(int j=1;j 100)
b=a;
_asm//棘手的部分从这里开始:
{
movups xmm0,a
movups xmm1,b
pmuludq xmm0,xmm0
pmuludq xmm1,xmm1
//movups xmm2,0
//paddxmm2,xmm0
//paddxmm2,xmm1
movz,xmm0
}
printf(“%d\n”,z);
}
}
}

您的方法的基本问题是,您需要并行查看4个
b
值,因此不能仅从C标量变量加载。您需要在循环迭代中保持向量寄存器中的内容,因为您不仅仅是从内存或其他地方加载向量。您应该在asm中编写整个循环,因为MSVC内联asm不适合包装短序列,这是因为获取结果的开销不可避免

当然,将此循环矢量化的最佳方法是使用C intrinsic,而不是使用内联asm。然后,如果有必要(如果可能的话),您可以通过检查编译器的asm输出的低效性来帮助编译器生成更好的asm。(见附件)


当然,如果您真的只是想创建高效的代码来生成毕达哥拉斯三元组,那么您的算法也是假的:

维基百科的文章有一节描述了欧几里德的公式。迭代这将是一个不同于在整个
a=[1..100]b=[1..100]
搜索空间的暴力搜索中检查命中率的问题,因为检查一个数字是否是一个完美的正方形相当慢


此外,检测与条件匹配的向量元素也很笨拙。压缩比较指令和PMOVMSKB(或MOVMSKPS)将为您提供位图,但这在命中次数很少时最有效,例如,在第一次命中后循环停止的位置实现
memchr

“我想在汇编中执行此操作,因为我知道它比C快。”您怎么知道?因为它可能不会。我不会假设您手工编写的asm将比C编译器的输出更快。编译器是智能的,现代CPU是复杂的。我以为所有的形式都是
n*(a*a=b+c)
之类的?一些数学运算应该比C和汇编更快。如果你想学习asm,可以在asm中编写整个循环(或者更好,编写整个函数)。以这种方式使用MSVC内联asm只会让你自食其果。请参阅,这也解释了为什么MSVC内联asm在这方面很糟糕。@Blorgbeard和Rukass:几乎总是可以用手写asm打败编译器,但你必须知道自己在做什么。通常最好从优化的编译器输出开始,这样至少不会做得更糟。但是通常最好的办法是在你找到了什么是最优的之后,调整你的C源代码,使编译器能够生成更好的asm。请参阅my了解更多信息。请注意,在台式计算机上检查整个
a=[1..100]b=[1..100]
搜索空间的时间平均不到.005秒,因此这个问题的整个前提是荒谬的。@user3386109:这仍然是一百万或两个核心时钟周期,足够长,可以用性能计数器精确测量。但显然,这一点更适用于更大的搜索范围。在每次搜索命中的时候调用<代码> PROTFF <代码>是荒谬的,而不是把它们存储在一个数组中。