【发布时间】:2011-04-20 13:02:17
【问题描述】:
我正在研究一个细粒度的动力学问题。计算量大的部分是下面的函数,它求解一个二次方程来检测两个粒子的碰撞。
我想知道这是否可以轻松优化,或者我是否正在做一些明显愚蠢的事情?例如,使用这些const double x1 = p1->x; 结构来给编译器一个提示是个好主意吗?查看汇编代码,编译器使用 SSE 指令,但我不知道它们是否在任何方面都是最优的(可能不是)。根据分析器,大部分时间都花在计算表达式a、b 和c 上。当您尝试优化如下所示的某些内核功能时,您(通常)会做什么?
void detect_collision_of_pair(struct particle* p1, struct particle* p2){
const double x1 = p1->x;
const double y1 = p1->y;
const double z1 = p1->z;
const double x2 = p2->x;
const double y2 = p2->y;
const double z2 = p2->z;
const double vx1 = p1->vx;
const double vy1 = p1->vy;
const double vz1 = p1->vz;
const double vx2 = p2->vx;
const double vy2 = p2->vy;
const double vz2 = p2->vz;
const double a = vx1*vx1 - 2.*vx1*vx2 + vx2*vx2 + vy1*vy1 - 2.*vy1*vy2 + vy2*vy2 + vz1*vz1 - 2.*vz1*vz2 + vz2*vz2;
const double b = 2.*vx1*x1 - 2.*vx2*x1 - 2.*vx1*x2 + 2.*vx2*x2 + 2.*vy1*y1 - 2.*vy2*y1 - 2.*vy1*y2 + 2.*vy2*y2 + 2.*vz1*z1 - 2.*vz2*z1 - 2.*vz1*z2 + 2.*vz2*z2;
const double c = -4.*particle_radius*particle_radius + x1*x1 - 2.*x1*x2 + x2*x2 + y1*y1 - 2.*y1*y2 + y2*y2 + z1*z1 - 2.*z1*z2 + z2*z2;
double root = b*b-4.*a*c;
if (root>=0.){
root = sqrt(root);
double time1 = (-b-root)/(2.*a);
double time2 = (-b+root)/(2.*a);
if ( (time1>-dt && time1<0.) || (time1<-dt && time2>0) ){
double times = -dt;
if (time1>-dt || time2<0){
if (time1>-dt){
times = time1;
}else{
times = time2;
}
}
resolve_collision(p1,p2,times);
}
}
}
【问题讨论】:
-
谢谢大家。到目前为止,我的速度提高了 30%。
标签: c optimization sse