Использование памяти odeint и время выполнения
Я заметил, что odeint использует очень мало памяти по сравнению с моей реализацией алгоритма RK4 или Mathematica. Для того же размера шага, odeint использует около 3,11 ГБ, в то время как моя программа использует 7 ГБ, а в Mathematica я должен вручную увеличить размер файла подкачки до 40 ГБ, иначе ему не хватит памяти. (Изменить: загрузка процессора составляет всего 18%)
Мне любопытно, как это возможно, потому что, когда я сохраняю результаты, файл данных имеет почти одинаковый размер во всех трех случаях.
Однако, когда дело доходит до времени выполнения, odeint кажется на порядок медленнее, чем моя программа или Mathematica. Это нормальный обмен? Я делаю вещи супер нуб.
Изменить: 2** Размер шага против времени выполнения **
- 0,0005=2:55,59 ~ 24,44 часа для 500 шагов
- 0,001=1:29,14 ~ 12,5 часа для 500 шагов
- 0,005= 0:17,19~ 2,5 часа для 500 шагов.
- 0,01= 8,34 ~ 1 час 10 минут для 500 шагов
Например:
void Classical(vector<vector<double> >& u1,vector<vector<double> >& u2,vector<vector<double> >& phi1,vector<double>& delta,vector<vector<double> >& theta,vector<vector<double> >& phi2, vector<double>& Gamma,vector<double>& z,double h,double u10,double u20,double theta_initial){
for(int i=0;i<delta.size();++i){
double v1=u10;
double v2=u20;
double ph1=0.0;
double ph2=0.0;
double angle=delta[i]; //OK
u1.push_back ( vector<double>() );
u2.push_back ( vector<double>() );
phi1.push_back ( vector<double>() );
phi2.push_back ( vector<double>() );
theta.push_back ( vector<double>() );
for(int j=0;j<z.size();++j){
double k1=0.0; double k2=0.0;double k3=0.0;double k4=0.0;
double L1=0.0; double L2=0.0;double L3=0.0;double L4=0.0;
double m1=0.0; double m2=0.0;double m3=0.0;double m4=0.0;
double n1=0.0; double n2=0.0;double n3=0.0;double n4=0.0;
k1=h*(v2*v2-1.0)*cos((angle));
L1=h*( (2.0/(1.0-(v2*v2))) - (1.0/(v2*v2)) )*Gamma[i];
m1=h*(1.0/(1.0-(v2*v2)))*Gamma[i];
n1=h*(1.0/((v2*v2)))*Gamma[i];
k2=h*((v2+k1/2)*(v2+k1/2)-1)*cos(((angle+L1/2)));
L2=h*( (2.0/(1-((v2+k1/2)*(v2+k1/2)))) - (1/((v2+k1/2)*(v2+k1/2))) )*Gamma[i];
m2=h*(1/(1-((v2+k1/2)*(v2+k1/2))))*Gamma[i];
n2=h*(1/(((v2+k1/2)*(v2+k1/2))))*Gamma[i];
k3=h*((v2+k2/2)*(v2+k2/2)-1)*cos(((angle+L2/2)));
L3=h*( (2.0/(1-((v2+k2/2)*(v2+k2/2)))) - (1/((v2+k2/2)*(v2+k2/2))) )*Gamma[i];
m3=h*(1/(1-((v2+k2/2)*(v2+k2/2))))*Gamma[i];
n3=h*(1/(((v2+k2/2)*(v2+k2/2))))*Gamma[i];
k4=h*((v2+k3)*(v2+k3)-1)*cos(((angle+L3)));
L4=h*( (2.0/(1-((v2+k3)*(v2+k3)))) - (1/((v2+k3)*(v2+k3))) )*Gamma[i];
m4=h*(1/(1-((v2+k3)*(v2+k3))))*Gamma[i];
n4=h*(1/(((v2+k3)*(v2+k3))))*Gamma[i];
v2=v2+(k1/6)+(k2/3)+(k3/3)+(k4/6);
angle=angle + (L1/6)+(L2/3)+(L3/3)+(L4/6);
ph1=ph1+(m1/6)+(m2/3)+(m3/3)+(m4/6);
ph2=ph2+(n1/6)+(n2/3)+(n3/3)+(n4/6);
v1=sqrt(1.0-(v2*v2));
u1[i].push_back(v1);
u2[i].push_back(v2);
theta[i].push_back(angle);
phi1[i].push_back(ph1);
phi2[i].push_back(ph2);
}
}
}
1 ответ
Я думаю, что вы должны компилировать свои программы в режиме выпуска, чтобы включить оптимизацию компилятора. odeint использует много шаблонного кода, который довольно медленный при компиляции в режиме отладки. Производительность будет увеличена на порядок в модусе выпуска.