我在组装方面非常新,我想找到1到100范围内的所有毕达哥拉斯三元组。我在C中生成所有数字,所有其他计算应该在汇编SSE中完成。我试图通过使用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);
}
}
}
答案 0 :(得分:2)
您的方法的基本问题是您需要并行查看4个b
值,因此您无法从C标量变量加载。你需要在循环迭代中将东西保存在向量寄存器中,因为你不是只是从内存或其他东西加载向量。您应该在asm中编写整个循环,因为MSVC内联asm很容易包装短序列,因为结果输入/输出不可避免的开销。
当然,对这个循环进行矢量化的最好方法是使用C内在函数,而不是使用内联asm。然后,如果需要(并且如果可能的话),您可以通过检查其asm输出来实现低效率,从而将编译器手动保持为更好的asm。 (见Why is this C++ code faster than my hand-written assembly for testing the Collatz conjecture?)
当然,如果你真的只想创建生成毕达哥拉斯三元组的高效代码,那么你的算法也是假的:
维基百科文章有一个generating a triple部分,描述了欧几里德的公式。迭代这将是一个不同的问题,而不是检查整个a=[1..100] b=[1..100]
搜索空间的强力搜索中的命中,因为检查数字是否是一个完美的正方形是相当慢的。
另外,检测哪些向量元素与条件匹配是笨拙的。打包比较指令然后PMOVMSKB(或MOVMSKPS)会给你一个位图,但是当命中很少时,这种方法效果最好,例如:实现memchr
,在第一次点击后你的循环停止。