use_dll: turn getPowerDeriv() and sign() into inline functions

This allows the compiler to better optimize by inlining those call when worth
it.
master
Sébastien Villemot 2023-04-11 15:29:12 +02:00
parent 1b7b70ec93
commit faa1291055
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
4 changed files with 25 additions and 29 deletions

View File

@ -894,7 +894,8 @@ DataTree::writeCHelpersDefinition(ostream &output) const
{
if (isBinaryOpUsed(BinaryOpcode::powerDeriv))
output << "// The k-th derivative of x^p" << endl
<< "double getPowerDeriv(double x, double p, int k)" << endl
<< "inline double" << endl
<< "getPowerDeriv(double x, double p, int k)" << endl
<< "{" << endl
<< " if (fabs(x) < " << power_deriv_near_zero << " && p > 0 && k > p && fabs(p-nearbyint(p)) < " << power_deriv_near_zero << ')' << endl
<< " return 0.0;" << endl
@ -908,7 +909,8 @@ DataTree::writeCHelpersDefinition(ostream &output) const
<< "}" << endl;
if (isUnaryOpUsed(UnaryOpcode::sign))
output << "double sign(double x)" << endl
output << "inline double" << endl
<< "sign(double x)" << endl
<< "{" << endl
<< " return (x > 0) ? 1 : ((x < 0) ? -1 : 0);" << endl
<< "}" << endl;
@ -918,9 +920,9 @@ void
DataTree::writeCHelpersDeclaration(ostream &output) const
{
if (isBinaryOpUsed(BinaryOpcode::powerDeriv))
output << "double getPowerDeriv(double x, double p, int k);" << endl;
output << "extern inline double getPowerDeriv(double x, double p, int k);" << endl;
if (isUnaryOpUsed(UnaryOpcode::sign))
output << "double sign(double x);" << endl;
output << "extern inline double sign(double x);" << endl;
}
vector<string>

View File

@ -277,9 +277,14 @@ public:
//! Returns the minimum lag (as a negative number) of the given symbol in the whole data tree (and not only in the equations !!)
/*! Returns 0 if the symbol is not used */
int minLagForSymbol(int symb_id) const;
//! Writes definitions of C function helpers (getPowerDeriv(), sign())
/* Writes definitions of C function helpers (getPowerDeriv(), sign()) as
inline functions */
void writeCHelpersDefinition(ostream &output) const;
//! Writes declarations of C function helpers (getPowerDeriv(), sign())
/* Writes declarations of C function helpers (getPowerDeriv(), sign()) as
extern inline (external definition). Those need to be included in exactly
one translation unit. That external definition will be used or not,
depending on the optimization decision by the compiler.
See https://en.cppreference.com/w/c/language/inline */
void writeCHelpersDeclaration(ostream &output) const;
//! Thrown when trying to access an unknown variable by deriv_id
class UnknownDerivIDException

View File

@ -973,7 +973,7 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext,
output << "#include <math.h>" << endl
<< R"(#include "mex.h")" << endl // Needed for calls to external functions
<< endl;
writeCHelpersDeclaration(output);
writeCHelpersDefinition(output);
output << endl
<< prototype_tt << endl
<< "{" << endl
@ -1012,7 +1012,9 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext,
output << "#include <math.h>" << endl
<< R"(#include "mex.h")" << endl // Needed for calls to external functions
<< endl;
writeCHelpersDeclaration(output);
writeCHelpersDefinition(output);
if (i == 0)
writeCHelpersDeclaration(output); // Provide external definition of helpers in resid main file
output << endl
<< prototype_main << endl
<< "{" << endl
@ -1041,10 +1043,6 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext,
<< R"(#include "mex.h")" << endl;
for (const auto &it : header_files)
output << "#include " << it.filename() << endl;
output << endl;
writeCHelpersDefinition(output);
output << endl
<< "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl
<< "{" << endl;
@ -2640,18 +2638,6 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
}
};
/* Write source files for the derivative of the power function.
NB: The prefix (static/dynamic) is added to the filename (even though its
the same source between static and dynamic) to avoid a race condition when
static and dynamic are compiled in parallel. */
filesystem::path helpers_src {model_src_dir / (prefix + "helpers.c")};
open_file(helpers_src);
output << "#include <math.h>" << endl << endl;
writeCHelpersDefinition(output);
output.close();
auto helpers_object {compileMEX(model_src_dir, (prefix + "helpers"),
mexext, { helpers_src }, matlabroot, false)};
size_t ttlen {0};
// Helper for dealing with y, x, params and steady_state inputs (shared with block case)
@ -2719,7 +2705,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
output << "#include <math.h>" << endl
<< R"(#include "mex.h")" << endl // Needed for calls to external functions
<< endl;
writeCHelpersDeclaration(output);
writeCHelpersDefinition(output);
output << endl
<< prototype_tt << endl
<< "{" << endl
@ -2742,7 +2728,8 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
output << "#include <math.h>" << endl
<< R"(#include "mex.h")" << endl // Needed for calls to external functions
<< endl;
writeCHelpersDeclaration(output);
writeCHelpersDefinition(output);
writeCHelpersDeclaration(output); // Provide external definition of helpers in main file
output << endl
<< prototype_main << endl
<< "{" << endl
@ -2831,7 +2818,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
<< "}" << endl;
output.close();
vector<filesystem::path> mex_input_files { helpers_object, main_object_file, source_mex };
vector<filesystem::path> mex_input_files { main_object_file, source_mex };
for (int j {0}; j <= i; j++)
mex_input_files.push_back(tt_object_files[j]);
compileMEX(mex_dir, funcname, mexext, mex_input_files, matlabroot);
@ -2860,7 +2847,8 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
output << "#include <math.h>" << endl
<< R"(#include "mex.h")" << endl
<< endl;
writeCHelpersDeclaration(output);
writeCHelpersDefinition(output);
writeCHelpersDeclaration(output); // Provide external definition of helpers
output << endl
<< "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl
<< "{" << endl
@ -2924,7 +2912,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
}
output << "}" << endl;
output.close();
compileMEX(block_dir, funcname, mexext, { source_mex, helpers_object }, matlabroot);
compileMEX(block_dir, funcname, mexext, { source_mex }, matlabroot);
}
}
}

View File

@ -921,6 +921,7 @@ StaticModel::writeRamseyMultipliersDerivativesCFile(const string &basename, cons
<< R"(#include "mex.h")" << endl // Needed for calls to external functions
<< endl;
writeCHelpersDefinition(output);
writeCHelpersDeclaration(output); // Provide external definition of helpers
output << endl
<< "void ramsey_multipliers_static_g1(const double *restrict y, const double *restrict x, const double *restrict params, double *restrict T, double *restrict g1m_v)" << endl
<< "{" << endl;