home Forums # Technical Support Execution speed Reply To: Execution speed

#2020
Unknown
Member

Hi,

I have loaded symbols from pdb files in visual studio 2013 to do performance analysis with cpu sampling.
see below for most time consuming functions:

Nom de la fonction	Échantillons inclusifs	Échantillons exclusifs	% d'échantillons inclusifs	% d'échantillons exclusifs
std::_Lockit::_Lockit	                7 216	7 216	3,07	3,07
operator delete	                        7 145	7 145	3,04	3,04
std::_Lockit::~_Lockit	                7 121	7 121	3,03	3,03
operator new	                        5 456	5 456	2,32	2,32
fl::Antecedent::activationDegree	78 861	5 094	33,56	2,17
_RTC_CheckStackVars	                3 684	3 684	1,57	1,57
_RTC_CheckEsp	                        3 654	3 654	1,56	1,56
std::_Iterator_base12::_Orphan_me	3 216	3 216	1,37	1,37
fl::Operation::isEq	                7 520	3 131	3,20	1,33
__RTDynamicCast	                        3 105	3 105	1,32	1,32
fl::Accumulated::membership	        19 031	2 979	8,10	1,27
free	                                2 970	2 970	1,26	1,26
fl::Ramp::membership	                13 160	2 931	5,60	1,25
std::_Iterator_base12::_Adopt	        11 232	2 875	4,78	1,22
_BitBlt@36	                        2 814	2 814	1,20	1,20
fl::Operation::isNaN<double>	        2 700	2 700	1,15	1,15
fl::Activated::membership	        12 797	2 531	5,45	1,08
std::_Iterator_base12::operator=	11 659	1 616	4,96	0,69
std::_Iterator_base12::~_Iterator_base12	11 895	1 460	5,06	0,62
_VEC_memset	                        1 226	1 226	0,52	0,52
std::_Iterator_base12::_Iterator_base12	12 937	1 199	5,51	0,51
std::_Container_base12::_Orphan_all	1 127	1 127	0,48	0,48
fl::Centroid::defuzzify	                20 968	954	8,92	0,41
std::vector<fl::Activated *,std::allocator<fl::Activated *> >::size	827	827	0,35	0,35
std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<fl::Hedge *> > >::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<fl::Hedge *> > >	14 616	730	6,22	0,31
std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<fl::Hedge *> > >::~_Vector_const_iterator<std::_Vector_val<std::_Simple_types<fl::Hedge *> > >	14 033	669	5,97	0,28
std::reverse_iterator<std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<fl::Hedge *> > > >::reverse_iterator<std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<fl::Hedge *> > > >	16 290	596	6,93	0,25
std::_Iterator012<std::random_access_iterator_tag,fl::Hedge *,int,fl::Hedge * const *,fl::Hedge * const &,std::_Iterator_base12>::_Iterator012<std::random_access_iterator_tag,fl::Hedge *,int,fl::Hedge * const *,fl::Hedge * const &,std::_Iterator_base12>	13 700	586	5,83	0,25
fl::Operation::isLt	2 929	574	1,25	0,24

I have deleted lines related to other libraries.
Dynamical allocation is very time consuming.
I have replaced dynamic_cast by static_cast for Variable but there is no significant improvement.

In Antecedent::activationDegree function, bottlenecks are at this lines :

28.9%: return conjunction->compute(
                    this->activationDegree(conjunction, disjunction, fuzzyOperator->left),
                    this->activationDegree(conjunction, disjunction, fuzzyOperator->right));
10.4%: if (fuzzyOperator->name == Rule::andKeyword()) {

6.9%: for (std::vector<Hedge*>::const_reverse_iterator rit = proposition->hedges.rbegin();
8.9%:                    rit != proposition->hedges.rend(); ++rit) {

2.1%: result = proposition->term->membership(inputVariable->getInputValue());

FFLL library is basic but fast, there are some explanations here :

I need a fast library because I optimize a parameter so there are a lot of call to engine::process function.
see below my controller:

engine = new fl::Engine("fuzzy_engine");
	
osc = new fl::InputVariable("OSC", -300, 300);
osc->setInputValue(0);
osc->setEnabled(true);
osc->addTerm(new fl::Ramp("UP", -134, -300));
osc->addTerm(new fl::Ramp("DOWN", 134, 300));
osc->addTerm(new fl::Ramp("EXIT_UP", -100, -300));
osc->addTerm(new fl::Ramp("EXIT_DOWN", 100, 300));
engine->addInputVariable(osc);
	
dosc = new fl::InputVariable();
dosc->setName("DOSC");
dosc->setRange(-300, 300);
dosc->setEnabled(true);
dosc->addTerm(new fl::Ramp("DOWN", 0,  -300));
dosc->addTerm(new fl::Ramp("UP", 0, 300));
engine->addInputVariable(dosc );

dvar2 = new fl::InputVariable("DVAR2", -100, 100);
dvar2->setInputValue(0);
dvar2->addTerm(new fl::Ramp("DOWN", -4.3, -100));
dvar2->addTerm(new fl::Ramp("UP", 4.3, 100));
engine->addInputVariable(dvar2);

dvar3 = new fl::InputVariable();
dvar3->setName("DVAR3");
dvar3->setRange(-5, 5);
dvar3->setEnabled(true);
dvar3->addTerm(new fl::Ramp("DOWN", -0.8, -5));
dvar3->addTerm(new fl::Ramp("UP", 0.8, 5));
engine->addInputVariable(dvar3 );

dvar12 = new fl::InputVariable();
dvar12->setName("DVAR12");
dvar12->setRange(-10, 10);
dvar12->setEnabled(true);
dvar12->addTerm(new fl::Ramp("DOWN", 0, -10));
dvar12->addTerm(new fl::Ramp("UP", 0, 10));
engine->addInputVariable(dvar12);

dvar1a = new fl::InputVariable();
dvar1a->setName("DVAR1A");
dvar1a->setRange(-30, 30);
dvar1a->setEnabled(true);
dvar1a->addTerm(new fl::Ramp("DOWN", -2, -10));
dvar1a->addTerm(new fl::Ramp("UP", 2, 10));
dvar1a->addTerm(new fl::Ramp("EXIT_DOWN", -17, -30));
dvar1a->addTerm(new fl::Ramp("EXIT_UP", 17, 30));
engine->addInputVariable(dvar1a );

dvarb1 = new fl::InputVariable();
dvarb1->setName("DVARB1");
dvarb1->setRange(-30, 30);
dvarb1->setEnabled(true);
dvarb1->addTerm(new fl::Ramp("UP", -2, -10));
dvarb1->addTerm(new fl::Ramp("DOWN", 2, 10));
dvarb1->addTerm(new fl::Ramp("EXIT_UP", -17, -30));
dvarb1->addTerm(new fl::Ramp("EXIT_DOWN", 17, 30));
engine->addInputVariable(dvarb1 );

entry = new fl::OutputVariable("ENTRY", -1, 1);
entry->setDefaultValue(0.0);
entry->setEnabled(true);
entry->fuzzyOutput()->setAccumulation(new fl::Maximum);
entry->setDefuzzifier(new fl::Centroid(200));
entry->addTerm(new fl::Ramp("ENTRY1", 0, -1));
entry->addTerm(new fl::Ramp("ENTRY2", 0, 1));
engine->addOutputVariable(entry);

exit = new fl::OutputVariable("EXIT", -1, 1);
exit->setDefaultValue(0.0);
exit->setEnabled(true);
exit->fuzzyOutput()->setAccumulation(new fl::Maximum);
exit->setDefuzzifier(new fl::Centroid(200));
exit->addTerm(new fl::Ramp("EXIT2", 0, -1));
exit->addTerm(new fl::Ramp("EXIT1", 0, 1));
engine->addOutputVariable(exit);

ruleblock = new fl::RuleBlock("rules");
ruleblock->setEnabled(true);
ruleblock->setConjunction(new fl::Minimum());
ruleblock->setDisjunction(new fl::Maximum);
ruleblock->setActivation(new fl::Minimum);
ruleblock->addRule(fl::Rule::parse("if OSC is DOWN and DOSC is DOWN and DVAR2 is DOWN and DVAR3 is DOWN and DVARB1 is DOWN then ENTRY is ENTRY2", engine));
ruleblock->addRule(fl::Rule::parse("if OSC is UP and DOSC is UP and DVAR2 is UP and DVAR3 is UP and DVAR1A is UP then ENTRY is ENTRY1", engine));
ruleblock->addRule(fl::Rule::parse("if OSC is EXIT_DOWN and DOSC is DOWN and DVARB1 is EXIT_DOWN then EXIT is EXIT1", engine));
ruleblock->addRule(fl::Rule::parse("if OSC is EXIT_UP and DOSC is UP and DVAR1A is EXIT_UP then EXIT is EXIT2", engine));

engine->addRuleBlock(ruleblock);

Thanks a lot for your help!

Cheers