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)
 | 
					EvalFunc::EvalFunc (const char* function, const char* x)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    expr = new ExprEval::Expression;
 | 
					    size_t nalloc = 1;
 | 
				
			||||||
    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);
 | 
					 | 
				
			||||||
#ifdef USE_OPENMP
 | 
					#ifdef USE_OPENMP
 | 
				
			||||||
    omp_init_lock(&lock);
 | 
					    nalloc = omp_get_max_threads();
 | 
				
			||||||
#endif
 | 
					#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) {
 | 
					  catch (ExprEval::Exception e) {
 | 
				
			||||||
    ExprException(e,"parsing",function);
 | 
					    ExprException(e,"parsing",function);
 | 
				
			||||||
@@ -108,31 +116,29 @@ EvalFunc::EvalFunc (const char* function, const char* x)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
EvalFunc::~EvalFunc ()
 | 
					EvalFunc::~EvalFunc ()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  delete expr;
 | 
					  for (auto& it : expr)
 | 
				
			||||||
  delete f;
 | 
					    delete it;
 | 
				
			||||||
  delete v;
 | 
					  for (auto& it : f)
 | 
				
			||||||
#ifdef USE_OPENMP
 | 
					    delete it;
 | 
				
			||||||
  omp_destroy_lock(&lock);
 | 
					  for (auto& it : v)
 | 
				
			||||||
#endif
 | 
					    delete it;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Real EvalFunc::evaluate (const Real& x) const
 | 
					Real EvalFunc::evaluate (const Real& x) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  size_t i = 0;
 | 
				
			||||||
#ifdef USE_OPENMP
 | 
					#ifdef USE_OPENMP
 | 
				
			||||||
  omp_set_lock(const_cast<omp_lock_t*>(&lock));
 | 
					  i = omp_get_thread_num();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
  Real result = Real(0);
 | 
					  Real result = Real(0);
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    *arg = x;
 | 
					    *arg[i] = x;
 | 
				
			||||||
    result = expr->Evaluate();
 | 
					    result = expr[i]->Evaluate();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  catch (ExprEval::Exception e) {
 | 
					  catch (ExprEval::Exception e) {
 | 
				
			||||||
    ExprException(e,"evaluating expression");
 | 
					    ExprException(e,"evaluating expression");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
#ifdef USE_OPENMP
 | 
					 | 
				
			||||||
  omp_unset_lock(const_cast<omp_lock_t*>(&lock));
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -141,25 +147,33 @@ Real EvalFunc::evaluate (const Real& x) const
 | 
				
			|||||||
EvalFunction::EvalFunction (const char* function)
 | 
					EvalFunction::EvalFunction (const char* function)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    expr = new ExprEval::Expression;
 | 
					    size_t nalloc = 1;
 | 
				
			||||||
    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");
 | 
					 | 
				
			||||||
#ifdef USE_OPENMP
 | 
					#ifdef USE_OPENMP
 | 
				
			||||||
    omp_init_lock(&lock);
 | 
					    nalloc = omp_get_max_threads();
 | 
				
			||||||
#endif
 | 
					#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) {
 | 
					  catch (ExprEval::Exception e) {
 | 
				
			||||||
    ExprException(e,"parsing",function);
 | 
					    ExprException(e,"parsing",function);
 | 
				
			||||||
@@ -174,35 +188,33 @@ EvalFunction::EvalFunction (const char* function)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
EvalFunction::~EvalFunction ()
 | 
					EvalFunction::~EvalFunction ()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  delete expr;
 | 
					  for (auto& it : expr)
 | 
				
			||||||
  delete f;
 | 
					    delete it;
 | 
				
			||||||
  delete v;
 | 
					  for (auto& it : f)
 | 
				
			||||||
#ifdef USE_OPENMP
 | 
					    delete it;
 | 
				
			||||||
  omp_destroy_lock(&lock);
 | 
					  for (auto& it : v)
 | 
				
			||||||
#endif
 | 
					    delete it;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Real EvalFunction::evaluate (const Vec3& X) const
 | 
					Real EvalFunction::evaluate (const Vec3& X) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const Vec4* Xt = dynamic_cast<const Vec4*>(&X);
 | 
					  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);
 | 
					  Real result = Real(0);
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    *x = X.x;
 | 
					    size_t i = 0;
 | 
				
			||||||
    *y = X.y;
 | 
					#ifdef USE_OPENMP
 | 
				
			||||||
    *z = X.z;
 | 
					    i = omp_get_thread_num();
 | 
				
			||||||
    *t = Xt ? Xt->t : Real(0);
 | 
					#endif
 | 
				
			||||||
    result = expr->Evaluate();
 | 
					    *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) {
 | 
					  catch (ExprEval::Exception e) {
 | 
				
			||||||
    ExprException(e,"evaluating expression");
 | 
					    ExprException(e,"evaluating expression");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
#ifdef USE_OPENMP
 | 
					 | 
				
			||||||
  omp_unset_lock(const_cast<omp_lock_t*>(&lock));
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@
 | 
				
			|||||||
#include "Function.h"
 | 
					#include "Function.h"
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <array>
 | 
				
			||||||
#ifdef USE_OPENMP
 | 
					#ifdef USE_OPENMP
 | 
				
			||||||
#include <omp.h>
 | 
					#include <omp.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -34,11 +35,11 @@ namespace ExprEval {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class EvalFunc : public ScalarFunc
 | 
					class EvalFunc : public ScalarFunc
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  ExprEval::Expression* expr; //!< Pointer to the root of the expression tree
 | 
					  std::vector<ExprEval::Expression*> expr; //!< Roots of the expression tree
 | 
				
			||||||
  ExprEval::FunctionList*  f; //!< Pointer to list of function in the expression
 | 
					  std::vector<ExprEval::FunctionList*>  f; //!< Lists of functions
 | 
				
			||||||
  ExprEval::ValueList*     v; //!< Pointer to list of variables and constants
 | 
					  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:
 | 
					public:
 | 
				
			||||||
  //! \brief The constructor parses the expression string.
 | 
					  //! \brief The constructor parses the expression string.
 | 
				
			||||||
@@ -49,11 +50,6 @@ public:
 | 
				
			|||||||
protected:
 | 
					protected:
 | 
				
			||||||
  //! \brief Evaluates the function expression.
 | 
					  //! \brief Evaluates the function expression.
 | 
				
			||||||
  virtual Real evaluate(const Real& x) const;
 | 
					  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
 | 
					class EvalFunction : public RealFunc
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  ExprEval::Expression* expr; //!< Pointer to the root of the expression tree
 | 
					  std::vector<ExprEval::Expression*> expr; //!< Roots of the expression tree
 | 
				
			||||||
  ExprEval::FunctionList*  f; //!< Pointer to list of function in the expression
 | 
					  std::vector<ExprEval::FunctionList*>  f; //!< Lists of functions
 | 
				
			||||||
  ExprEval::ValueList*     v; //!< Pointer to list of variables and constants
 | 
					  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
 | 
					  bool  IAmConstant; //!< Indicates whether the time coordinate is given or not
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@@ -85,11 +78,6 @@ public:
 | 
				
			|||||||
protected:
 | 
					protected:
 | 
				
			||||||
  //! \brief Evaluates the function expression.
 | 
					  //! \brief Evaluates the function expression.
 | 
				
			||||||
  virtual Real evaluate(const Vec3& X) const;
 | 
					  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:
 | 
					public:
 | 
				
			||||||
  //! \brief The constructor parses the expression string for each component.
 | 
					  //! \brief The constructor parses the expression string for each component.
 | 
				
			||||||
  EvalMultiFunction<ParentFunc,Ret>(const std::string& functions,
 | 
					  EvalMultiFunction<ParentFunc,Ret>(const std::string& functions,
 | 
				
			||||||
                                    const std::string& variables="")
 | 
					                                    const std::string& variables = "")
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    size_t pos = functions.find("|"), pos2 = 0;
 | 
					    size_t pos = functions.find("|"), pos2 = 0;
 | 
				
			||||||
    for (int i = 0; pos2 < functions.size(); i++)
 | 
					    for (int i = 0; pos2 < functions.size(); i++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      std::string func(variables);
 | 
					      std::string func(variables);
 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (!func.empty() && func[func.size()-1] != ';')
 | 
					      if (!func.empty() && func[func.size()-1] != ';')
 | 
				
			||||||
        func += ';';
 | 
					        func += ';';
 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (pos == std::string::npos)
 | 
					      if (pos == std::string::npos)
 | 
				
			||||||
        func += functions.substr(pos2);
 | 
					        func += functions.substr(pos2);
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user