diff --git a/Apps/Tuto/show_traversors.cpp b/Apps/Tuto/show_traversors.cpp index cee2c8ab93da7c546fe56168459d1d10f1f7b63c..a2177f1f5990b3e955707ad96509769ece9ee8b0 100644 --- a/Apps/Tuto/show_traversors.cpp +++ b/Apps/Tuto/show_traversors.cpp @@ -32,9 +32,7 @@ #include "Algo/Render/GL2/topo3Render.h" #include "Algo/Render/SVG/mapSVGRender.h" -//#include "Topology/generic/traversor3.h" -//#include "Topology/generic/traversor3.h" -#include "Topology/generic/traversorGen.h" +#include "Topology/generic/traversorFactory.h" #include "Algo/Render/GL2/drawerCells.h" @@ -214,7 +212,7 @@ void MyQT::traverse2() { Algo::Render::drawerCell(VERTEX+m_second2, m_drawer, myMap, m_selected, position, m_expl); m_drawer.color3f(1.0f,0.0f,0.0f); - Traversor* tra = Traversor::createIncident(myMap, m_selected, 2, VERTEX+m_second2, VERTEX+m_first2); + Traversor* tra = TraversorFactory::createIncident(myMap, m_selected, 2, VERTEX+m_second2, VERTEX+m_first2); for (Dart d=tra->begin(); d != tra->end(); d= tra->next()) m_affDarts.push_back(d); Algo::Render::drawerCells(VERTEX+m_first2, m_drawer, myMap, m_affDarts, position, m_expl); @@ -223,7 +221,7 @@ void MyQT::traverse2() { Algo::Render::drawerCell(VERTEX+m_first2, m_drawer, myMap, m_selected, position, m_expl); m_drawer.color3f(1.0f,0.0f,0.0f); - Traversor* tra = Traversor::createAdjacent(myMap, m_selected, 2, VERTEX+m_first2, VERTEX+m_second2); + Traversor* tra = TraversorFactory::createAdjacent(myMap, m_selected, 2, VERTEX+m_first2, VERTEX+m_second2); for (Dart d = tra->begin(); d != tra->end(); d = tra->next()) m_affDarts.push_back(d); Algo::Render::drawerCells(VERTEX+m_first2, m_drawer, myMap, m_affDarts, position, m_expl); @@ -286,7 +284,7 @@ void MyQT::traverse3() dynamicMarkOrbit(VERTEX+m_second3); m_drawer.color3f(1.0f,0.0f,0.0f); - Traversor* tra = Traversor::createIncident(myMap,m_selected, 3, VERTEX+m_second3, VERTEX+m_first3); + Traversor* tra = TraversorFactory::createIncident(myMap,m_selected, 3, VERTEX+m_second3, VERTEX+m_first3); for (Dart d = tra->begin(); d != tra->end(); d = tra->next()) { m_affDarts.push_back(d); @@ -306,7 +304,7 @@ void MyQT::traverse3() dynamicMarkOrbit(VERTEX+m_first3); m_drawer.color3f(1.0f,0.0f,0.0f); - Traversor* tra = Traversor::createAdjacent(myMap,m_selected, 3, VERTEX+m_first3, VERTEX+m_second3); + Traversor* tra = TraversorFactory::createAdjacent(myMap,m_selected, 3, VERTEX+m_first3, VERTEX+m_second3); for (Dart d = tra->begin(); d != tra->end(); d = tra->next()) { m_affDarts.push_back(d); diff --git a/Apps/Tuto/tuto_orbits.cpp b/Apps/Tuto/tuto_orbits.cpp index 02fed74e76c605cbc2cdba644f0b221ad9b71673..dddb0f25c20a07bb7c64c8542159c3a01bc82927 100644 --- a/Apps/Tuto/tuto_orbits.cpp +++ b/Apps/Tuto/tuto_orbits.cpp @@ -35,6 +35,7 @@ #include "Algo/Render/SVG/mapSVGRender.h" #include "Algo/Import/import.h" +#include "Topology/generic/traversorFactory.h" MAP myMap; VertexAttribute position ; @@ -66,7 +67,7 @@ void MyQT::orbit_list(int x) m_selected.clear(); // easy way to traverse darts of orbit - Traversor* tra = Traversor::createDartsOfOrbits(myMap,m_clicked,orbs[current_orbit]); + Traversor* tra = TraversorFactory::createDartsOfOrbits(myMap,m_clicked,orbs[current_orbit]); for (Dart e = tra->begin(); e != tra->end(); e = tra->next()) m_selected.push_back(e); } @@ -174,7 +175,7 @@ void MyQT::cb_mousePress(int button, int x, int y) m_selected.clear(); // easy way to traverse darts of orbit - Traversor* tra = Traversor::createDartsOfOrbits(myMap,m_clicked,orbs[current_orbit]); + Traversor* tra = TraversorFactory::createDartsOfOrbits(myMap,m_clicked,orbs[current_orbit]); for (Dart e = tra->begin(); e != tra->end(); e = tra->next()) m_selected.push_back(e); } diff --git a/include/Algo/Parallel/parallel_foreach.h b/include/Algo/Parallel/parallel_foreach.h index fa34cb3aa7f236a25db30d139a982b737911efb0..ded4b3017150fda85d047f01c83f54cb775d946b 100644 --- a/include/Algo/Parallel/parallel_foreach.h +++ b/include/Algo/Parallel/parallel_foreach.h @@ -22,11 +22,12 @@ * * *******************************************************************************/ -#include "Topology/generic/functor.h" #ifndef __PARALLEL_FOREACH__ #define __PARALLEL_FOREACH__ +#include "Topology/generic/functor.h" + namespace CGoGN { @@ -36,6 +37,11 @@ namespace Algo namespace Parallel { +static unsigned int NBCORES=0; + +/// enum for optimalNbThreads parameter +enum NbParam {NB_HIGHMEMORY, NB_HIGHCOMPUTE, NB_VERYHIGHMEMORY}; + /// size of buffers to store darts or indexes in each threads const unsigned int SIZE_BUFFER_THREAD = 8192; // seems to be the best compromise @@ -45,9 +51,15 @@ const unsigned int SIZE_BUFFER_THREAD = 8192; // seems to be the best compromise inline unsigned int nbThreads(); /** + * @param p can be NB_HIGHMEMORY (default) or NB_HIGHCOMPUTE or NB_VERYHIGHMEMORY * @return Number of core in fact (work only with quad core with/without hyper threading) */ -inline unsigned int optimalNbThreads(); +unsigned int optimalNbThreads( NbParam p=NB_HIGHMEMORY); + +/** + * impossible to automatically determine the number of cores so ... + */ +void setNbCore(unsigned int nb); /** diff --git a/include/Algo/Parallel/parallel_foreach.hpp b/include/Algo/Parallel/parallel_foreach.hpp index d4777cc8af995da9c256da6364120424e447b114..0adf72afd394be4617bef75f72a743c316e4787c 100644 --- a/include/Algo/Parallel/parallel_foreach.hpp +++ b/include/Algo/Parallel/parallel_foreach.hpp @@ -25,6 +25,7 @@ #include #include + namespace CGoGN { @@ -34,6 +35,7 @@ namespace Algo namespace Parallel { +/// internal functor for boost call class ThreadFunctionAttrib { protected: @@ -66,11 +68,7 @@ public: }; - - -/** - * - */ +/// internal functor for boost call template class ThreadFunction { @@ -109,17 +107,25 @@ inline unsigned int nbThreads() } - -inline unsigned int optimalNbThreads() +inline unsigned int optimalNbThreads(NbParam p) { + if (p==NB_HIGHCOMPUTE) + return nbThreads(); + if (p==NB_VERYHIGHMEMORY) + return 2; + + // NB_HIGHMEMORY + if (NBCORES != 0) + return NBCORES; unsigned int nb = nbThreads(); if (nb>4) return nb/2 ; - return nb; + } + template void foreach_cell(MAP& map, FunctorMapThreaded& func, unsigned int nbth, bool needMarkers, const FunctorSelect& good, unsigned int currentThread) { @@ -144,7 +150,6 @@ void foreach_cell(MAP& map, FunctorMapThreaded& func, unsigned int nbth, bo funcs.push_back(func.duplicate()); } - foreach_cell(map,funcs,nbth,needMarkers,good,currentThread); if (!shared) @@ -164,7 +169,6 @@ void foreach_cell(MAP& map, std::vector*>& funcs, unsign for (unsigned int i = 0; i < nbth; ++i) vd[i].reserve(SIZE_BUFFER_THREAD); - AttributeContainer* cont = NULL; DartMarker* dmark = NULL; CellMarker* cmark = NULL; @@ -413,7 +417,6 @@ void foreach_dart(MAP& map, std::vector*> funcs, unsigne for (unsigned int i = 0; i < nbth; ++i) { -// funcs[i]->setThreadID(1+i); threads[i] = new boost::thread(ThreadFunction(funcs[i], vd[i],sync1,sync2, finished,1+i)); } @@ -461,103 +464,6 @@ void foreach_dart(MAP& map, std::vector*> funcs, unsigne } - -inline void foreach_attrib(AttributeContainer& attr_cont, FunctorAttribThreaded& func, unsigned int nbth) -{ - if (nbth == 0) - nbth = optimalNbThreads(); - - std::vector funcs; - funcs.reserve(nbth); - - FunctorAttribThreaded* ptr = func.duplicate(); - bool shared = (ptr == NULL); - - if (shared) - { - for (unsigned int i = 0; i < nbth; ++i) - funcs.push_back(&func); - } - else - { - funcs.push_back(ptr); - for (unsigned int i = 1; i < nbth; ++i) - funcs.push_back(func.duplicate()); - } - - foreach_attrib(attr_cont,funcs,nbth); - - if (!shared) - for (unsigned int i = 0; i < nbth; ++i) - delete funcs[i]; - -} - - -inline void foreach_attrib(AttributeContainer& attr_cont, std::vector funcs, unsigned int nbth) -{ - assert(funcs.size() == nbth); - - std::vector* vid = new std::vector[2*nbth]; - boost::thread** threads = new boost::thread*[nbth]; - - for (unsigned int i = 0; i < 2*nbth; ++i) - vid[i].reserve(SIZE_BUFFER_THREAD); - - // fill each vid buffers with 4096 id - unsigned int id = attr_cont.begin(); - unsigned int nb = 0; - unsigned int nbm = nbth*SIZE_BUFFER_THREAD; - while ((id != attr_cont.end()) && (nb < nbm)) - { - vid[nb%nbth].push_back(id); - nb++; - attr_cont.next(id); - } - - - boost::barrier sync1(nbth+1); - boost::barrier sync2(nbth+1); - bool finished=false; - // lauch threads - for (unsigned int i = 0; i < nbth; ++i) - threads[i] = new boost::thread(ThreadFunctionAttrib(funcs[i], vid[i],sync1,sync2, finished,1+i)); - - while (id != attr_cont.end()) - { - for (unsigned int i = nbth; i < 2*nbth; ++i) - vid[i].clear(); - - unsigned int nb = 0; - while ((id != attr_cont.end()) && (nb < nbm)) - { - vid[nbth + nb%nbth].push_back(id); - nb++; - attr_cont.next(id); - } - - sync1.wait(); - for (unsigned int i = 0; i < nbth; ++i) - vid[i].swap(vid[nbth+i]); - sync2.wait(); - } - - sync1.wait(); - finished = true; - sync2.wait(); - - //wait for all theads to be finished - for (unsigned int i = 0; i < nbth; ++i) - { - threads[i]->join(); - delete threads[i]; - } - delete[] threads; - delete[] vid; -} - - - // TODO same modification for transparent usage of dart marker / cell marker / quick traversal template diff --git a/include/Topology/generic/traversor3.h b/include/Topology/generic/traversor3.h index dad38e69b0b7a0d041dd2f9ea09a90cb7e6f8a93..435eaeaed56b2d47e8937786981d3262f1fda53e 100644 --- a/include/Topology/generic/traversor3.h +++ b/include/Topology/generic/traversor3.h @@ -21,14 +21,15 @@ * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ -#include "Topology/generic/traversorGen.h" #ifndef __TRAVERSOR3_H__ #define __TRAVERSOR3_H__ -#include "Topology/generic/dart.h" #include "Topology/generic/traversorCell.h" - +#include "Topology/generic/traversorGen.h" +#include "Topology/generic/traversorDoO.h" +#include "Topology/generic/dart.h" +#include "Topology/generic/cellmarker.h" namespace CGoGN { diff --git a/include/Topology/generic/traversorCell.h b/include/Topology/generic/traversorCell.h index 1de7f2aa353c6d425036a699f5c01a5c94c3c11a..7f5127a213c20d4849eeee09e42a3030c5e9bcc8 100644 --- a/include/Topology/generic/traversorCell.h +++ b/include/Topology/generic/traversorCell.h @@ -22,14 +22,13 @@ * * *******************************************************************************/ -#include "Topology/generic/traversorGen.h" - #ifndef __TRAVERSOR_CELL_H__ #define __TRAVERSOR_CELL_H__ #include "Topology/generic/dart.h" #include "Topology/generic/dartmarker.h" #include "Topology/generic/cellmarker.h" +#include "Topology/generic/traversorGen.h" namespace CGoGN { @@ -98,24 +97,6 @@ public: {} }; - -template -class TraversorDartsOfOrbit : public Traversor -{ -private: - std::vector::iterator m_current ; - std::vector m_vd ; - -public: - TraversorDartsOfOrbit(MAP& map, Dart d, unsigned int thread = 0) ; - - Dart begin() ; - - Dart end() ; - - Dart next() ; -} ; - } // namespace CGoGN #include "Topology/generic/traversorCell.hpp" diff --git a/include/Topology/generic/traversorCell.hpp b/include/Topology/generic/traversorCell.hpp index a012d73625c2aa0edb58d46799b6d7bc0b1bfae2..449ab25eaa54920ae91007c8c5da057578443365 100644 --- a/include/Topology/generic/traversorCell.hpp +++ b/include/Topology/generic/traversorCell.hpp @@ -153,35 +153,35 @@ void TraversorCell::skip(Dart d) cmark->mark(d) ; } - -template -TraversorDartsOfOrbit::TraversorDartsOfOrbit(MAP& map, Dart d, unsigned int thread) -{ - m_vd.reserve(16); - FunctorStoreNotBoundary fs(map, m_vd); - map.template foreach_dart_of_orbit(d, fs, thread); - m_vd.push_back(NIL); -} - -template -Dart TraversorDartsOfOrbit::begin() -{ - m_current = m_vd.begin(); - return *m_current; -} - -template -Dart TraversorDartsOfOrbit::end() -{ - return NIL; -} - -template -Dart TraversorDartsOfOrbit::next() -{ - if (*m_current != NIL) - m_current++; - return *m_current; -} +// +//template +//TraversorDartsOfOrbit::TraversorDartsOfOrbit(MAP& map, Dart d, unsigned int thread) +//{ +// m_vd.reserve(16); +// FunctorStoreNotBoundary fs(map, m_vd); +// map.template foreach_dart_of_orbit(d, fs, thread); +// m_vd.push_back(NIL); +//} +// +//template +//Dart TraversorDartsOfOrbit::begin() +//{ +// m_current = m_vd.begin(); +// return *m_current; +//} +// +//template +//Dart TraversorDartsOfOrbit::end() +//{ +// return NIL; +//} +// +//template +//Dart TraversorDartsOfOrbit::next() +//{ +// if (*m_current != NIL) +// m_current++; +// return *m_current; +//} } // namespace CGoGN diff --git a/include/Topology/generic/traversorFactory.h b/include/Topology/generic/traversorFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..b4137245e0a36fffe3f75a135375da430bc56aa4 --- /dev/null +++ b/include/Topology/generic/traversorFactory.h @@ -0,0 +1,86 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __TRAVERSORFACTORY_H__ +#define __TRAVERSORGEN_H__ + +#include "Topology/generic/traversorGen.h" + +namespace CGoGN +{ + +template +class TraversorFactory +{ +public: + + /** + * Factory of incident traversors creation + * @param map the map in which we work + * @param dart the initial dart of traversal + * @param dim the dimension of traversal (2 or 3) + * @param orbX incident from cell + * @param orbY incident to cell + * @return a ptr on Generic Traversor + */ + static Traversor* createIncident(MAP& map, Dart dart, unsigned int dim, unsigned int orbX, unsigned int orbY); + + /** + * Factory of adjacent traversors creation + * @param map the map in which we work + * @param dart the initial dart of traversal + * @param dim the dimension of traversal (2 or 3) + * @param orbX incident from cell + * @param orbY incident to cell + * @return a ptr on Generic Traversor + */ + static Traversor* createAdjacent(MAP& map, Dart dart, unsigned int dim, unsigned int orbX, unsigned int orbY); + + /** + * Factory of darts of orbit traversors creation + * @param map the map in which we work + * @param dart the initial dart of traversal + * @param orb the orbit + * @return a ptr on Generic Traversor + */ + static Traversor* createDartsOfOrbits(MAP& map, Dart dart, unsigned int orb); + + /** + * Factory of incident traversors creation + * @param map the map in which we work + * @param good the selector (default value allDarts) + * @param forceDartMarker (default value false) + * @param thread (default value 0) + * @return a ptr on Generic Traversor + */ + static Traversor* createCell(MAP& map, unsigned int orb, const FunctorSelect& good = allDarts, bool forceDartMarker = false, unsigned int thread = 0); +}; + +} // namespace CGoGN + + +#include "Topology/generic/traversorFactory.hpp" + +#endif + diff --git a/include/Topology/generic/traversorGen.hpp b/include/Topology/generic/traversorFactory.hpp similarity index 93% rename from include/Topology/generic/traversorGen.hpp rename to include/Topology/generic/traversorFactory.hpp index 05444095efe7d0b1b87c4a4d48ee57399dc962da..04bd8e1a3c9de7d7d51411175f52df3e1423357d 100644 --- a/include/Topology/generic/traversorGen.hpp +++ b/include/Topology/generic/traversorFactory.hpp @@ -25,12 +25,13 @@ #include "Topology/generic/traversor2.h" #include "Topology/generic/traversor3.h" #include "Topology/generic/traversorCell.h" +#include "Topology/generic/traversorDoO.h" namespace CGoGN { template -Traversor* Traversor::createIncident(MAP& map, Dart dart, unsigned int dim, unsigned int orbX, unsigned int orbY) +Traversor* TraversorFactory::createIncident(MAP& map, Dart dart, unsigned int dim, unsigned int orbX, unsigned int orbY) { int code = 0x100*dim + 0x10*(orbX-VERTEX) + orbY-VERTEX; @@ -114,7 +115,7 @@ Traversor* Traversor::createIncident(MAP& map, Dart dart, unsigned int template -Traversor* Traversor::createAdjacent(MAP& map, Dart dart, unsigned int dim, unsigned int orbX, unsigned int orbY) +Traversor* TraversorFactory::createAdjacent(MAP& map, Dart dart, unsigned int dim, unsigned int orbX, unsigned int orbY) { int code = 0x100*dim + 0x10*(orbX-VERTEX) + orbY-VERTEX; @@ -191,16 +192,14 @@ Traversor* Traversor::createAdjacent(MAP& map, Dart dart, unsigned int default: return NULL; break; - } - return NULL; } template -Traversor* Traversor::createCell(MAP& map, unsigned int orb, const FunctorSelect& good, bool forceDartMarker, unsigned int thread) +Traversor* TraversorFactory::createCell(MAP& map, unsigned int orb, const FunctorSelect& good, bool forceDartMarker, unsigned int thread) { switch(orb) { @@ -241,7 +240,7 @@ Traversor* Traversor::createCell(MAP& map, unsigned int orb, const Fun } template -Traversor* Traversor::createDartsOfOrbits(MAP& map, Dart dart, unsigned int orb) +Traversor* TraversorFactory::createDartsOfOrbits(MAP& map, Dart dart, unsigned int orb) { switch(orb) { @@ -282,10 +281,6 @@ Traversor* Traversor::createDartsOfOrbits(MAP& map, Dart dart, unsigne } - - - - } diff --git a/include/Topology/generic/traversorGen.h b/include/Topology/generic/traversorGen.h index ee0c819699986d54f12673a7bdcf5494da178b26..bf4e4fd4e0903c187638cfddae212b7647f1f7bf 100644 --- a/include/Topology/generic/traversorGen.h +++ b/include/Topology/generic/traversorGen.h @@ -84,7 +84,7 @@ public: } // namespace CGoGN -#include "Topology/generic/traversorGen.hpp" +//#include "Topology/generic/traversorGen.hpp" #endif diff --git a/src/Algo/ImplicitHierarchicalMesh/ihm3.cpp b/src/Algo/ImplicitHierarchicalMesh/ihm3.cpp index 9ed2d422a01bfd69d191e88f53ee633fe814a8aa..ce63e007dedc61d7026e954506fb1ef63e86838c 100644 --- a/src/Algo/ImplicitHierarchicalMesh/ihm3.cpp +++ b/src/Algo/ImplicitHierarchicalMesh/ihm3.cpp @@ -23,6 +23,7 @@ *******************************************************************************/ #include "Algo/ImplicitHierarchicalMesh/ihm3.h" +#include "Topology/generic/traversor3.h" #include #include diff --git a/src/Algo/Parallel/parallel_foreach.cpp b/src/Algo/Parallel/parallel_foreach.cpp new file mode 100644 index 0000000000000000000000000000000000000000..48e7cdb88edc94685e2256fd83a4599a3508d793 --- /dev/null +++ b/src/Algo/Parallel/parallel_foreach.cpp @@ -0,0 +1,140 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ +#include "Topology/generic/genericmap.h" +#include "Algo/Parallel/parallel_foreach.h" + + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Parallel +{ + +void setNbCore(unsigned int nb) +{ + NBCORES = nb; +} + + + +void foreach_attrib(AttributeContainer& attr_cont, FunctorAttribThreaded& func, unsigned int nbth) +{ + if (nbth == 0) + nbth = optimalNbThreads(); + + std::vector funcs; + funcs.reserve(nbth); + + FunctorAttribThreaded* ptr = func.duplicate(); + bool shared = (ptr == NULL); + + if (shared) + { + for (unsigned int i = 0; i < nbth; ++i) + funcs.push_back(&func); + } + else + { + funcs.push_back(ptr); + for (unsigned int i = 1; i < nbth; ++i) + funcs.push_back(func.duplicate()); + } + + foreach_attrib(attr_cont,funcs,nbth); + + if (!shared) + for (unsigned int i = 0; i < nbth; ++i) + delete funcs[i]; + +} + +void foreach_attrib(AttributeContainer& attr_cont, std::vector funcs, unsigned int nbth) +{ + assert(funcs.size() == nbth); + + std::vector* vid = new std::vector[2*nbth]; + boost::thread** threads = new boost::thread*[nbth]; + + for (unsigned int i = 0; i < 2*nbth; ++i) + vid[i].reserve(SIZE_BUFFER_THREAD); + + // fill each vid buffers with 4096 id + unsigned int id = attr_cont.begin(); + unsigned int nb = 0; + unsigned int nbm = nbth*SIZE_BUFFER_THREAD; + while ((id != attr_cont.end()) && (nb < nbm)) + { + vid[nb%nbth].push_back(id); + nb++; + attr_cont.next(id); + } + + + boost::barrier sync1(nbth+1); + boost::barrier sync2(nbth+1); + bool finished=false; + // lauch threads + for (unsigned int i = 0; i < nbth; ++i) + threads[i] = new boost::thread(ThreadFunctionAttrib(funcs[i], vid[i],sync1,sync2, finished,1+i)); + + while (id != attr_cont.end()) + { + for (unsigned int i = nbth; i < 2*nbth; ++i) + vid[i].clear(); + + unsigned int nb = 0; + while ((id != attr_cont.end()) && (nb < nbm)) + { + vid[nbth + nb%nbth].push_back(id); + nb++; + attr_cont.next(id); + } + + sync1.wait(); + for (unsigned int i = 0; i < nbth; ++i) + vid[i].swap(vid[nbth+i]); + sync2.wait(); + } + + sync1.wait(); + finished = true; + sync2.wait(); + + //wait for all theads to be finished + for (unsigned int i = 0; i < nbth; ++i) + { + threads[i]->join(); + delete threads[i]; + } + delete[] threads; + delete[] vid; +} + + +} +} // end namespaces +}