changed: instantiate one expr function per thread
this avoids the need for a lock
This commit is contained in:
committed by
Knut Morten Okstad
parent
184b9c31e7
commit
3357188686
@@ -86,19 +86,27 @@ static void ExprException (const ExprEval::Exception& exc, const char* task,
|
||||
EvalFunc::EvalFunc (const char* function, const char* x)
|
||||
{
|
||||
try {
|
||||
expr = new ExprEval::Expression;
|
||||
f = new ExprEval::FunctionList;
|
||||
v = new ExprEval::ValueList;
|
||||
f->AddDefaultFunctions();
|
||||
v->AddDefaultValues();
|
||||
v->Add(x,0,false);
|
||||
expr->SetFunctionList(f);
|
||||
expr->SetValueList(v);
|
||||
expr->Parse(function);
|
||||
arg = v->GetAddress(x);
|
||||
size_t nalloc = 1;
|
||||
#ifdef USE_OPENMP
|
||||
omp_init_lock(&lock);
|
||||
nalloc = omp_get_max_threads();
|
||||
#endif
|
||||
expr.resize(nalloc);
|
||||
f.resize(nalloc);
|
||||
v.resize(nalloc);
|
||||
expr.resize(nalloc);
|
||||
arg.resize(nalloc);
|
||||
for (size_t i = 0; i < nalloc; ++i) {
|
||||
expr[i] = new ExprEval::Expression;
|
||||
f[i] = new ExprEval::FunctionList;
|
||||
v[i] = new ExprEval::ValueList;
|
||||
f[i]->AddDefaultFunctions();
|
||||
v[i]->AddDefaultValues();
|
||||
v[i]->Add(x,0,false);
|
||||
expr[i]->SetFunctionList(f[i]);
|
||||
expr[i]->SetValueList(v[i]);
|
||||
expr[i]->Parse(function);
|
||||
arg[i] = v[i]->GetAddress(x);
|
||||
}
|
||||
}
|
||||
catch (ExprEval::Exception e) {
|
||||
ExprException(e,"parsing",function);
|
||||
@@ -108,31 +116,29 @@ EvalFunc::EvalFunc (const char* function, const char* x)
|
||||
|
||||
EvalFunc::~EvalFunc ()
|
||||
{
|
||||
delete expr;
|
||||
delete f;
|
||||
delete v;
|
||||
#ifdef USE_OPENMP
|
||||
omp_destroy_lock(&lock);
|
||||
#endif
|
||||
for (auto& it : expr)
|
||||
delete it;
|
||||
for (auto& it : f)
|
||||
delete it;
|
||||
for (auto& it : v)
|
||||
delete it;
|
||||
}
|
||||
|
||||
|
||||
Real EvalFunc::evaluate (const Real& x) const
|
||||
{
|
||||
size_t i = 0;
|
||||
#ifdef USE_OPENMP
|
||||
omp_set_lock(const_cast<omp_lock_t*>(&lock));
|
||||
i = omp_get_thread_num();
|
||||
#endif
|
||||
Real result = Real(0);
|
||||
try {
|
||||
*arg = x;
|
||||
result = expr->Evaluate();
|
||||
*arg[i] = x;
|
||||
result = expr[i]->Evaluate();
|
||||
}
|
||||
catch (ExprEval::Exception e) {
|
||||
ExprException(e,"evaluating expression");
|
||||
}
|
||||
#ifdef USE_OPENMP
|
||||
omp_unset_lock(const_cast<omp_lock_t*>(&lock));
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -141,25 +147,33 @@ Real EvalFunc::evaluate (const Real& x) const
|
||||
EvalFunction::EvalFunction (const char* function)
|
||||
{
|
||||
try {
|
||||
expr = new ExprEval::Expression;
|
||||
f = new ExprEval::FunctionList;
|
||||
v = new ExprEval::ValueList;
|
||||
f->AddDefaultFunctions();
|
||||
v->AddDefaultValues();
|
||||
v->Add("x",0,false);
|
||||
v->Add("y",0,false);
|
||||
v->Add("z",0,false);
|
||||
v->Add("t",0,false);
|
||||
expr->SetFunctionList(f);
|
||||
expr->SetValueList(v);
|
||||
expr->Parse(function);
|
||||
x = v->GetAddress("x");
|
||||
y = v->GetAddress("y");
|
||||
z = v->GetAddress("z");
|
||||
t = v->GetAddress("t");
|
||||
size_t nalloc = 1;
|
||||
#ifdef USE_OPENMP
|
||||
omp_init_lock(&lock);
|
||||
nalloc = omp_get_max_threads();
|
||||
#endif
|
||||
expr.resize(nalloc);
|
||||
f.resize(nalloc);
|
||||
v.resize(nalloc);
|
||||
expr.resize(nalloc);
|
||||
c.resize(nalloc);
|
||||
for (size_t i = 0; i < nalloc; ++i) {
|
||||
expr[i] = new ExprEval::Expression;
|
||||
f[i] = new ExprEval::FunctionList;
|
||||
v[i] = new ExprEval::ValueList;
|
||||
f[i]->AddDefaultFunctions();
|
||||
v[i]->AddDefaultValues();
|
||||
v[i]->Add("x",0,false);
|
||||
v[i]->Add("y",0,false);
|
||||
v[i]->Add("z",0,false);
|
||||
v[i]->Add("t",0,false);
|
||||
expr[i]->SetFunctionList(f[i]);
|
||||
expr[i]->SetValueList(v[i]);
|
||||
expr[i]->Parse(function);
|
||||
c[i][0] = v[i]->GetAddress("x");
|
||||
c[i][1] = v[i]->GetAddress("y");
|
||||
c[i][2] = v[i]->GetAddress("z");
|
||||
c[i][3] = v[i]->GetAddress("t");
|
||||
}
|
||||
}
|
||||
catch (ExprEval::Exception e) {
|
||||
ExprException(e,"parsing",function);
|
||||
@@ -174,35 +188,33 @@ EvalFunction::EvalFunction (const char* function)
|
||||
|
||||
EvalFunction::~EvalFunction ()
|
||||
{
|
||||
delete expr;
|
||||
delete f;
|
||||
delete v;
|
||||
#ifdef USE_OPENMP
|
||||
omp_destroy_lock(&lock);
|
||||
#endif
|
||||
for (auto& it : expr)
|
||||
delete it;
|
||||
for (auto& it : f)
|
||||
delete it;
|
||||
for (auto& it : v)
|
||||
delete it;
|
||||
}
|
||||
|
||||
|
||||
Real EvalFunction::evaluate (const Vec3& X) const
|
||||
{
|
||||
const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
|
||||
#ifdef USE_OPENMP
|
||||
omp_set_lock(const_cast<omp_lock_t*>(&lock));
|
||||
#endif
|
||||
Real result = Real(0);
|
||||
try {
|
||||
*x = X.x;
|
||||
*y = X.y;
|
||||
*z = X.z;
|
||||
*t = Xt ? Xt->t : Real(0);
|
||||
result = expr->Evaluate();
|
||||
size_t i = 0;
|
||||
#ifdef USE_OPENMP
|
||||
i = omp_get_thread_num();
|
||||
#endif
|
||||
*c[i][0] = X.x;
|
||||
*c[i][1] = X.y;
|
||||
*c[i][2] = X.z;
|
||||
*c[i][3] = Xt ? Xt->t : Real(0);
|
||||
result = expr[i]->Evaluate();
|
||||
}
|
||||
catch (ExprEval::Exception e) {
|
||||
ExprException(e,"evaluating expression");
|
||||
}
|
||||
#ifdef USE_OPENMP
|
||||
omp_unset_lock(const_cast<omp_lock_t*>(&lock));
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "Function.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#ifdef USE_OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
@@ -34,11 +35,11 @@ namespace ExprEval {
|
||||
|
||||
class EvalFunc : public ScalarFunc
|
||||
{
|
||||
ExprEval::Expression* expr; //!< Pointer to the root of the expression tree
|
||||
ExprEval::FunctionList* f; //!< Pointer to list of function in the expression
|
||||
ExprEval::ValueList* v; //!< Pointer to list of variables and constants
|
||||
std::vector<ExprEval::Expression*> expr; //!< Roots of the expression tree
|
||||
std::vector<ExprEval::FunctionList*> f; //!< Lists of functions
|
||||
std::vector<ExprEval::ValueList*> v; //!< Lists of variables and constants
|
||||
|
||||
Real* arg; //!< Pointer to the function argument
|
||||
std::vector<Real*> arg; //!< Function argument values
|
||||
|
||||
public:
|
||||
//! \brief The constructor parses the expression string.
|
||||
@@ -49,11 +50,6 @@ public:
|
||||
protected:
|
||||
//! \brief Evaluates the function expression.
|
||||
virtual Real evaluate(const Real& x) const;
|
||||
|
||||
private:
|
||||
#ifdef USE_OPENMP
|
||||
omp_lock_t lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -63,14 +59,11 @@ private:
|
||||
|
||||
class EvalFunction : public RealFunc
|
||||
{
|
||||
ExprEval::Expression* expr; //!< Pointer to the root of the expression tree
|
||||
ExprEval::FunctionList* f; //!< Pointer to list of function in the expression
|
||||
ExprEval::ValueList* v; //!< Pointer to list of variables and constants
|
||||
std::vector<ExprEval::Expression*> expr; //!< Roots of the expression tree
|
||||
std::vector<ExprEval::FunctionList*> f; //!< Lists of functions
|
||||
std::vector<ExprEval::ValueList*> v; //!< Lists of variables and constants
|
||||
std::vector<std::array<Real*,4>> c; //!< Function argument values
|
||||
|
||||
Real* x; //!< Pointer to the X-coordinate of the function argument
|
||||
Real* y; //!< Pointer to the Y-coordinate of the function argument
|
||||
Real* z; //!< Pointer to the Z-coordinate of the function argument
|
||||
Real* t; //!< Pointer to the time coordinate of the function argument
|
||||
bool IAmConstant; //!< Indicates whether the time coordinate is given or not
|
||||
|
||||
public:
|
||||
@@ -85,11 +78,6 @@ public:
|
||||
protected:
|
||||
//! \brief Evaluates the function expression.
|
||||
virtual Real evaluate(const Vec3& X) const;
|
||||
|
||||
private:
|
||||
#ifdef USE_OPENMP
|
||||
omp_lock_t lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -106,16 +94,14 @@ class EvalMultiFunction : public ParentFunc
|
||||
public:
|
||||
//! \brief The constructor parses the expression string for each component.
|
||||
EvalMultiFunction<ParentFunc,Ret>(const std::string& functions,
|
||||
const std::string& variables="")
|
||||
const std::string& variables = "")
|
||||
{
|
||||
size_t pos = functions.find("|"), pos2 = 0;
|
||||
for (int i = 0; pos2 < functions.size(); i++)
|
||||
{
|
||||
std::string func(variables);
|
||||
|
||||
if (!func.empty() && func[func.size()-1] != ';')
|
||||
func += ';';
|
||||
|
||||
if (pos == std::string::npos)
|
||||
func += functions.substr(pos2);
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user