关于MIC的奇怪结果

时间:2014-09-18 13:35:15

标签: c++ optimization physics vectorization xeon-phi

对于我的论文,我运行了一个简单的代码,用于在Xeon Phi协处理器上研究Lennard Jones系统,我试图对其进行矢量化并研究执行时间的变化。
我特别使用的机器有61个内核,32 kB L1缓存和512 kB L2缓存,矢量寄存器可以记忆512位。

我使用和不使用单元格列表方法实现了代码,并使用了不同数量的粒子,特别是512到16384,每次都加倍。
位置和力量记忆在三个不同的矢量中(rx,ry,rz和fx,fy,fz)。
在没有单元格列表的情况下我得到了很好的结果,但在另一个中我得到了一些奇怪的结果。

单元列表和粒子数之间的依赖关系应该与实现的单元格列表方法呈线性关系,实际上我获得了一条直线绘制时间超过粒子数,但是N = 8192和N = 16384执行的时间要高得多 我尝试使用接近这些值的N值进行一些计算,但是对于每个其他数字,缩放是正确的,只有那两个存在问题。
为了说清楚,我报告了一些价值:

N      Time 
512    6.14995
1024   11.1381
2048   23.1964
4096   51.9393
6144   78.1251
8192   389.724
10240  144.173
12288  167.772
14336  209.669
16384  822.131

我认为这是一个技术问题,但我真的不知道为什么会发生这种情况 我还观察到使用矢量化的变化非常小,没有细胞列表我观察到因子4x的变化,或多或少,但是细胞列表只有1.5倍左右。

问题:

有人知道问题是什么吗?为什么这些特殊值很奇怪,为什么矢量化增益太低?

我的教授告诉我,有些值可能会在执行中显示出奇怪的结果,是否有人观察过这样的事情?

非常感谢。

下面我报告主要循环,用于评估力,用少数几个词来表示执行的主要部分,用单元列表实现。

for(vcy=0; vcy<ncell; vcy++){

    for(vcx=0; vcx<ncell; vcx++){

        previouspartc=0;

        // Central cell index
        c=vcx*ncell+vcy;

        // Define previouspart
        for(p=1; p<=c; p++) previouspartc=previouspartc+npart[p-1];

        // Loop over central cell's particles
        for(i=0; i<npart[c]-1; i++){

            for(j=i+1; j<npart[c]; j++){

                ftempx=0.; ftempy=0.;
                dx =rx1[previouspartc+i]-rx1[previouspartc+j];
                dy =ry1[previouspartc+i]-ry1[previouspartc+j];
                dx = (dx + 0.5*dy)*L;
                dy = dy*halfsq3*L;
                r2 = dx*dx + dy*dy;
                if(r2<r2cut) {

                    rr2 = 1./r2;
                    rr6 = rr2*rr2*rr2;
                    enk+=(c12*rr6 -c6)*rr6 -ecut;
                    vir=(cf12*rr6-cf6)*rr6*rr2;
                    ftempx=vir*dx; 
                    ftempy=vir*dy;
                }
                fx1[previouspartc+i]+=ftempx;               
                fy1[previouspartc+i]+=ftempy;
                fx1[previouspartc+j]-=ftempx;               
                fy1[previouspartc+j]-=ftempy;
            }
        }

        // Create the two indexes vcx1, vcy1 of the neighbour cells (the one on the right and the three under)
        vcx1[0]=vcx+1;   vcy1[0]=vcy;
        for(k=1; k<4; k++){

            vcx1[k]=vcx-1+(k-1);
            vcy1[k]=vcy-1;  
        }

        // Loop over near cells
        for(k=0; k<4; k++){

            previouspartc1=0;

            // PBC
            shiftx=0.; shifty=0.;

            if(vcx1[k] <0){ shiftx= -1; vcx1[k]=ncell-1;}

            else if(vcx1[k] >=ncell){ shiftx= 1; vcx1[k]=0;}

            if(vcy1[k] <0){ shifty= -1; vcy1[k]=ncell-1;}

            else if(vcy1[k] >=ncell){ shifty= 1; vcy1[k]=0;}    

            // Scalar cell index of neighbour cell
            c1=vcx1[k]*ncell+vcy1[k];


            // Define previouspart
            for(p=1; p<=c1; p++) previouspartc1=previouspartc1+npart[p-1];

            for(i=0; i<npart[c]; i++){

                for(j=0; j<npart[c1]; j++){

                    ftempx=0.; ftempy=0.;
                    dx =rx1[previouspartc+i]-(rx1[previouspartc1+j]+shiftx);
                    dy =ry1[previouspartc+i]-(ry1[previouspartc1+j]+shifty);
                    dx = (dx + 0.5*dy)*L;
                    dy = dy*halfsq3*L;
                    r2 = dx*dx + dy*dy;
                    if(r2<r2cut) {

                        rr2 = 1./r2;
                        rr6 = rr2*rr2*rr2;
                        enk+=(c12*rr6 -c6)*rr6 -ecut;
                        vir=(cf12*rr6-cf6)*rr6*rr2;
                        ftempx=vir*dx; 
                        ftempy=vir*dy;
                    }
                    fx1[previouspartc+i]+=ftempx;               
                    fy1[previouspartc+i]+=ftempy;
                    fx1[previouspartc1+j]-=ftempx;
                    fy1[previouspartc1+j]-=ftempy;
                }
            }
        } 
    }
}       

0 个答案:

没有答案