I just wrote a program to solve one dimensional Euler equation for fluid dynamics. Attached is a snippet of the vtune profile result for one of the function. There are a few things which looks weird to me. For example, difference in line 72 takes more time than division in line 70. Also line 70 takes more time than 69 which include a sqrt! Can anyone explain the discrepancy? Also suggestion to improve (in terms of performance) this piece of code is welcome.
This particular routine is called many times in the code so I want this to be as fast as possible.
Additional information:
This module is part of a multi-threaded program (using OpenMO).
I am using Intel C++ compiler, icpc, with -O3.
My ultimate aim is to run this code on Xeon-Phi.
Function
__declspec(vector) void roeflux(double rhol, double rhor, double ul, double ur, double pl, double pr,
double *f_0, double *f_1, double *f_2){
double el = pl/(GAMMA_M) + 0.5f*rhol*ul*ul;
double er = pr/(GAMMA_M) + 0.5f*rhor*ur*ur;
double hl = (el + pl)/rhol;
double hr = (er + pr)/rhor;
double sqrtrhol = sqrt(rhol);
double sqrtrhor = sqrt(rhor);
double den_inverse = 1/(sqrtrhol + sqrtrhor);
double uavg = (sqrtrhol*ul + sqrtrhor*ur)*den_inverse;
double havg = (sqrtrhol*hl + sqrtrhor*hr)*den_inverse;
double cavg = sqrt(GAMMA_M*(havg - 0.5f*uavg*uavg));
double cavg_inverse = 1.0f/cavg;
double d1 = rhor - rhol;
double d2 = rhor*ur - rhol*ul;
double d3 = er - el;
double alpha_2 = GAMMA_M*((havg - uavg*uavg)*d1 + uavg*d2 - d3)*cavg_inverse*cavg_inverse;
double alpha_3 = 0.5f*(d2 + (cavg - uavg)*d1 - cavg*alpha_2)*cavg_inverse;
double alpha_1 = d1 - alpha_2 - alpha_3;
double lambda_1 = fabs(uavg - cavg);
double lambda_2 = fabs(uavg);
double lambda_3 = fabs(uavg + cavg);
double f1 = lambda_1*alpha_1 + lambda_2*alpha_2 + lambda_3*alpha_3;
double f2 = lambda_1*alpha_1*(uavg-cavg) + lambda_2*alpha_2*uavg + lambda_3*alpha_3*(uavg+cavg);
double f3 = lambda_1*alpha_1*(havg-cavg*uavg) + 0.5f*lambda_2*alpha_2*uavg*uavg + lambda_3*alpha_3*(havg+cavg*uavg);
*f_0 = 0.5f*((rhol*ul + rhor*ur) - f1);
*f_1 = 0.5f*((rhol*ul*ul + pl + rhor*ur*ur + pr) - f2);
*f_2 = 0.5f*(ul*hl*rhol + ur*hr*rhor - f3);
}