gpt4 book ai didi

Java可以识别CPU的SIMD优势;或者只是循环展开的优化效果

转载 作者:搜寻专家 更新时间:2023-11-01 01:13:18 39 4
gpt4 key购买 nike

这部分代码来 self 的一个 vector 类的dotproduct方法。该方法对目标 vector 数组(1000个 vector )进行内积计算。

当 vector 长度为​​奇数(262145)时,计算时间为4.37秒。当 vector 长度(N)为262144(8的倍数)时,计算时间为1.93秒。

     time1=System.nanotime();
int count=0;
for(int j=0;j<1000;i++)
{

b=vektors[i]; // selects next vector(b) to multiply as inner product.
// each vector has an array of float elements.

if(((N/2)*2)!=N)
{
for(int i=0;i<N;i++)
{
t1+=elements[i]*b.elements[i];
}
}
else if(((N/8)*8)==N)
{
float []vek=new float[8];
for(int i=0;i<(N/8);i++)
{
vek[0]=elements[i]*b.elements[i];
vek[1]=elements[i+1]*b.elements[i+1];
vek[2]=elements[i+2]*b.elements[i+2];
vek[3]=elements[i+3]*b.elements[i+3];
vek[4]=elements[i+4]*b.elements[i+4];
vek[5]=elements[i+5]*b.elements[i+5];
vek[6]=elements[i+6]*b.elements[i+6];
vek[7]=elements[i+7]*b.elements[i+7];


t1+=vek[0]+vek[1]+vek[2]+vek[3]+vek[4]+vek[5]+vek[6]+vek[7];
//t1 is total sum of all dot products.
}
}
}
time2=System.nanotime();
time3=(time2-time1)/1000000000.0; //seconds

问题:时间从 4.37 秒减少到 1.93 秒(快 2 倍)是 JIT 使用 SIMD 指令的明智决定还是我的循环展开的积极影响?

如果 JIT 不能自动进行 SIMD 优化,那么在这个例子中也没有由 JIT 自动进行展开优化,是这样吗?

对于 1M 次迭代( vector )和 vector 大小为 64,加速乘数达到 3.5 倍(缓存优势?)。

谢谢。

最佳答案

您的代码有很多问题。你确定你在衡量你认为你在衡量的东西吗?

您的第一个循环执行此操作,缩进更常规:

 for(int j=0;j<1000;i++) {
b=vektors[i]; // selects next vector(b) to multiply as inner product.
// each vector has an array of float elements.
}

您的滚动循环涉及一个非常长的依赖加载和存储链。您展开的循环涉及 8 个独立的依赖加载和存储链。如果您使用浮点运算,JVM 无法将一个转换为另一个,因为它们是根本不同的计算。打破依赖的加载存储链可以显着提高现代处理器的速度。

您的滚动循环遍历整个 vector 。您展开的循环仅迭代第一个(大致)八分之一。因此,展开的循环再次计算出根本不同的东西。

我还没有看到 JVM 为类似您的第二个循环的东西生成矢量化代码,但我对 JVM 的作用可能已经过时了几年。运行代码并检查 opto 生成的代码时,尝试使用 -XX:+PrintAssembly

关于Java可以识别CPU的SIMD优势;或者只是循环展开的优化效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17459188/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com