今天晚上重新实现了C#的simd, 在我的i5 8265U上只需要1.8秒了,比simd 的C++的2.96秒还快很多。
需要说明的是,昨天直接用AVX2指令实现simd, 因为不支持除法,先把int转成float然后做除法。
结果一直不对,发现是对于比较大的i,转成float后精度损失了,所以结果就不对了。
今天用double实现,原来8路向量,现在只能4路。 但是结果还是不错的。 只要1.8秒。
比较赞的是dotnet把simd操作封装到Vector,不用考虑具体指令集了,也不用管cpu支持几路向量了,
jit会在运行时检查硬件。
C++的simd 要近3秒,是因为我用了SVML的整数取模指令,是intel用其他指令编程合成的,所以会慢。
如果也用double实现, 应该跟C#速度类似。
对C#的profiling, 向量除法运算这一语句耗时用到全部程序的50%。
public static int intperf3(int n)
{
int cc = 1;
int vn = Vector<double>.Count;
double[] buf = new double[n];
buf[0] = 2;
for (int i = 3; i <= n; i += 2)
{
int flag = 1;
int it = 0;
var vi = new Vector<double>(i);
int m = cc - vn;
for (; it < m; it += vn)
{
var vj = new Vector<double>(buf, it);
var t1 = vi/vj;
var t2 = Vector.Floor(t1);
if (Vector.EqualsAny(t1, t2))
{
flag = 0;
break;
}
double j = buf[it];
if (j * j > i)
break;
}
if (flag == 0) continue;
for (; it < cc; it++)
{
int j = (int)buf[it];
if (i % j == 0)
{
flag = 0;
break;
}
if (j*j > i)
break;
}
if (flag == 1)
{
buf[cc++] = i;
}
}
return cc;
}
【 在 leadu 的大作中提到: 】
: cpu密集的程序性能上,高级语言没有能比得上c/cpp/rust的,都会比他们多几条指令,多几纳秒。
: 定量5kw内求素数,上面也早就给了数据了,cpp确实快一些,但快的这一些,拉一下滚动条都能抵消,99.9%使用场景下没有值得考虑的价值
: cpu simd,gpu,fpga都是硬件优化范畴,本身使用的都是另外的接口,和语言本身无关,哪个语言也都能用
: ...................
--
FROM 123.112.64.*