我有一些代码运行得很好,但我想让它运行得更好。我对它的主要问题是它需要嵌套for循环。外层是用于迭代(它必须连续发生),内层是针对每个点粒子的考虑。我知道有没有什么我可以做外一个,但我不知道是否有优化类似的方式:SIMD值得吗?有更好的选择吗?
void collide(particle particles[], box boxes[],
double boxShiftX, double boxShiftY) {/*{{{*/
int i;
double nX;
double nY;
int boxnum;
for(i=0;i<PART_COUNT;i++) {
boxnum = ((((int)(particles[i].sX+boxShiftX))/BOX_SIZE)%BWIDTH+
BWIDTH*((((int)(particles[i].sY+boxShiftY))/BOX_SIZE)%BHEIGHT));
//copied and pasted the macro which is why it's kinda odd looking
particles[i].vX -= boxes[boxnum].mX;
particles[i].vY -= boxes[boxnum].mY;
if(boxes[boxnum].rotDir == 1) {
nX = particles[i].vX*Wxx+particles[i].vY*Wxy;
nY = particles[i].vX*Wyx+particles[i].vY*Wyy;
} else { //to make it randomly pick a rot. direction
nX = particles[i].vX*Wxx-particles[i].vY*Wxy;
nY = -particles[i].vX*Wyx+particles[i].vY*Wyy;
}
particles[i].vX = nX + boxes[boxnum].mX;
particles[i].vY = nY + boxes[boxnum].mY;
}
}/*}}}*/
我已经看了SIMD,虽然我不能找到太多有关它并且我不完全确定,正确提取和打包数据所需的处理值得获得执行一半指令的收益,因为显然一次只能使用两个双打。
我试图用shm和pthread_barrier将它分解成多个线程(同步上面的代码是不同的阶段),但它让它变慢了。
我目前的代码确实很快;每10M粒子*次迭代次数为1秒,从gprof中我可以看出,30%的时间仅用于该函数(5000次调用; PART_COUNT = 8192次粒子耗时1.8秒)。我并不担心小的恒定时间的事情,只是512K粒子* 50K迭代* 1000次实验上次超过一周。
我想我的问题是,如果有任何处理这些长矢量的方法比循环遍历它们更有效。我觉得应该有,但我找不到它。
感谢您接受我的回答。这些帮助有多少? – celion 2010-07-21 19:48:03