Я уже в торсионном треде спрашивал AntonI про числодробилки на плюсах, но возможно кто-нибудь ещё сможет дать совет по тому, как правильно оптимизировать вычисления на плюсах (фортран тоже сойдёт на самом деле, но нужны веские аргументы, как впрочем и питон с нумпаями).
Я вычисляю значение комплекснозначной функции от трёх действительных аргументов
(плюс ещё порядка тридцати действительных параметров, которые при вычислении
фиксированы на каждую итерацию фита). Пока я взял фортрановский код,
соответствующий данной статье, и
переписал его в виде класса с методами const
и double
. Пример ниже приведён.
Таких функций я должен буду насчитывать по миллиарду раз на только одну итерацию
фита, поэтому и встаёт вопрос об оптимальном написании кода.
Заголовочный файл вот такой:
#include <complex>
typedef std::complex<double> complex;
class ff_t
{
private:
double mro, gro, mrp, grp, mf2, gf2, mf0, gf0, msg, gsg;
complex bt1, bt2, bt3, bt4, bt5, bt6, bt7;
double mpi, mpi2;
double sqr (double x) const {return x*x;}
public:
ff_t ();
complex xi1 (double qq, double s1, double s2) const;
};
Кусок файла с кодом:
#include "ff.hpp"
#include <cmath>
complex ff_t::bw (double s, double m, double g, int l) const
{
const auto mp = 4*sqr (mpi);
const auto msq = sqr (m);
const auto w = std::sqrt (s);
double wgs = 0.0;
if (w>2*mpi) {
auto qs = std::sqrt (std::abs ((s-mp)*s))/w;
auto qm = std::sqrt (std::abs ((msq-mp)*msq))/m;
const int ipow = 2*l+1;
wgs = g*(msq/w)*std::pow(qs/qm, ipow);
}
return complex (msq, 0.)/ complex (msq-s, -wgs);
}
complex ff_t::xi1 (double qq, double s1, double s2) const
{
// check phase space
auto s3 = qq - s1 - s2 + 3*mpi2;
if ((s3 <= 0.) or (s2 <= 0.))
return complex(0., 0.);
const auto f134 = -1./3. * ((s3-mpi2)-(s1-mpi2));
const auto f15a = -1./2. * ((s2-mpi2)-(s3-mpi2));
const auto f15b = -1./18.* (qq-mpi2+s2)*(4.*mpi2-s2)/s2;
const auto f167 = -2./3.;
const auto fro1 = bw (s1, mro, gro/*o*/, 1);
const auto frp1 = bw (s1, mrp, grp, 1);
const auto fro2 = bw (s2, mro, gro, 1);
const auto frp2 = bw (s2, mrp, grp, 1);
const auto ff21 = bw (s1, mf2, gf2, 2);
const auto ff22 = bw (s2, mf2, gf2, 2);
const auto fsg2 = bw (s2, msg, gsg, 0);
const auto ff02 = bw (s2, mf0, gf0, 0);
return
bt1*fro1 + bt2*frp1+
bt3*f134*fro2 + bt4*f134*frp2
- bt5*f15a*ff21 - bt5*f15b*ff22
- bt6*f167*fsg2 - bt7*f167*ff02;
}
И флаги компиляции:
CFLAGS=-pthread -std=c++14 -m64 -fext-numeric-literals
CFLAGS += -Wall -Werror -Wpacked -malign-double -O3\
-mpreferred-stack-boundary=8 -Wfatal-errors