我有一些运行良好的代码,但我想让它运行得更好。我遇到的主要问题是它需要有一个嵌套的 for 循环。外层用于迭代(必须连续发生),内层用于考虑中的每个点粒子。我知道对于外部我无能为力,但我想知道是否有一种优化方法,例如:
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 次实验花了一周多的时间。
我想我的问题是,是否有任何方法可以处理这些长向量,而不仅仅是循环它们。我觉得应该有,但我找不到。