一个循环我有这样的结构的环矢量化其访问非连续的存储器位置
do z=1,zend
do y=1,yend
do x=1,xend
k=arr(x,y,z)
do while(k.ne.0)
ix=fooX(k)
iy=fooY(k)
iz=fooZ(k)
x1=x(ix ,iy ,iz)
x2=x(ix+1,iy ,iz)
x3=x(ix ,iy+1,iz)
x4=x(ix+1,iy+1,iz)
x5=x(ix ,iy ,iz+1)
x6=x(ix+1,iy ,iz+1)
x7=x(ix ,iy+1,iz+1)
x8=x(ix+1,iy+1,iz+1)
y1=y(ix ,iy ,iz)
y2=y(ix+1,iy ,iz)
y3=y(ix ,iy+1,iz)
y4=y(ix+1,iy+1,iz)
y5=y(ix ,iy ,iz+1)
y6=y(ix+1,iy ,iz+1)
y7=y(ix ,iy+1,iz+1)
y8=y(ix+1,iy+1,iz+1)
z1=z(ix ,iy ,iz)
z2=z(ix+1,iy ,iz)
z3=z(ix ,iy+1,iz)
z4=z(ix+1,iy+1,iz)
z5=z(ix ,iy ,iz+1)
z6=z(ix+1,iy ,iz+1)
z7=z(ix ,iy+1,iz+1)
z8=z(ix+1,iy+1,iz+1)
sumX+=x1+x2+..x8
sumY+=y1+y2+..y8
sumZ+=z1+z2+..z8
k=linkArr(k)
enddo
enddo
enddo
enddo
X1到X8是长方体的8个角。向量化代码有三个挑战。一个是8个数组元素在内存中不连续。其次是固有的while循环结构以及链接的List访问。第三,从fooX,fooY,fooZ返回的ix,iy,iz的值不是连续的。所以循环的每次迭代都有一组完全不同的ix,iy,iz。所以即使在迭代中,内存访问也是分散的。 我尝试以下方法:1。 展开的3级DO循环为:
do z=1,zend
do y=1,yend
do x=1,xend
if(arr(x,y,z).NE.0) then
kArr(indx)=arr(x,y,z)
DO WHILE (kArr(indx).NE.0)
indx = indx + 1
kArr(indx)=linkArr(kArr(indx-1))
ENDDO
endif
enddo
enddo
enddo
有了这个,我已经摆脱了while循环结构的,现在我能够在卡尔运行一个大循环其中我组8个元素(说我的VPU一次可以容纳8组数据)。它没有提高性能。如果有人感兴趣,我可以发布这些细节。我需要关于如何优化此代码的建议。我试过的另一个选择是将x,y,z数据组合到一个单独的数组中,这样当我计算x1时,z1也会在相邻的存储单元中。
你没有告诉我们足够的。值x1 ... x8,y1..y8,z1..z8发生了什么?代码呈现的方式现在可以全部消除,并且您没有计算问题,因为您的循环体即空。 – 2012-08-13 08:50:50
@IraBaxter:编辑了代码片段。感谢您指出或我的循环执行将毫无意义。 – arunmoezhi 2012-08-13 09:14:56
如果你真的想提高性能,那么你应该考虑使用SSE内在函数。 “希望”编译器能够生成快速/向量化的代码肯定会导致失望。我总是假定编译器生成糟糕的代码,并且时间关键部分需要用ASM或内部函数编写(这种假设通常是正确的)。 – BitBank 2012-08-16 01:19:23