Commit c4c16e07 authored by Sylvain Thery's avatar Sylvain Thery

thread C++11

parent 14c3f576
......@@ -464,46 +464,30 @@ void Viewer::cb_keyPress(int keycode)
Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices1 "<< ch.elapsed()<< " ms "<< std::endl;
// ch.start();
// CGoGN::Parallel::NumberOfThreads = 2;
// for (unsigned int i=0; i<4; ++i)
// Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
// std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices2 "<< ch.elapsed()<< " ms "<< std::endl;
// ch.start();
// CGoGN::Parallel::NumberOfThreads = 3;
// for (unsigned int i=0; i<4; ++i)
// Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
// std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices3 "<< ch.elapsed()<< " ms "<< std::endl;
ch.start();
CGoGN::Parallel::NumberOfThreads = 4;
CGoGN::Parallel::NumberOfThreads = 2;
for (unsigned int i=0; i<4; ++i)
Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices4 "<< ch.elapsed()<< " ms "<< std::endl;
// ch.start();
// CGoGN::Parallel::NumberOfThreads = 8;
// for (unsigned int i=0; i<4; ++i)
// Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
// std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices8 "<< ch.elapsed()<< " ms "<< std::endl;
std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices2 "<< ch.elapsed()<< " ms "<< std::endl;
ch.start();
CGoGN::Parallel::NumberOfThreads = 1;
CGoGN::Parallel::NumberOfThreads = 3;
for (unsigned int i=0; i<4; ++i)
Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices1 "<< ch.elapsed()<< " ms "<< std::endl;
std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices3 "<< ch.elapsed()<< " ms "<< std::endl;
ch.start();
CGoGN::Parallel::NumberOfThreads = 4;
for (unsigned int i=0; i<4; ++i)
Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices4 "<< ch.elapsed()<< " ms "<< std::endl;
ch.start();
CGoGN::Parallel::NumberOfThreads = 8;
for (unsigned int i=0; i<4; ++i)
Parallel::foreach_cell<VERTEX>(myMap, [&] (Vertex v, unsigned int th)
{
normal[v] = Algo::Surface::Geometry::vertexNormal<PFP>(myMap,v,position);
}, FORCE_CELL_MARKING);
Algo::Surface::Geometry::Parallel::computeNormalVertices<PFP>(myMap, position, normal) ;
std::cout << "Algo::Surface::Geometry::Parallel::computeNormalVertices8 "<< ch.elapsed()<< " ms "<< std::endl;
std::cout << "Parallel::foreach_cell "<< ch.elapsed()<< " ms "<< std::endl;
// ch.start();
// Parallel::foreach_cell_EO<VERTEX>(myMap,[&](Vertex v, unsigned int thr)
......
......@@ -439,8 +439,8 @@ int main(int argc, char **argv)
position = myMap.addAttribute<VEC3, VERTEX, MAP>("position");
int nb = 8;
Algo::Volume::Tilings::Cubic::Grid<PFP> cubic(myMap, nb, nb, nb);
cubic.embedIntoGrid(position, 1.0f, 1.0f, 1.0f);
Algo::Volume::Tilings::Cubic::Grid<PFP> cubic(myMap, nb, nb, 1);
cubic.embedIntoGrid(position, 1.0f, 1.0f, 0.0f);
for (unsigned int i = position.begin(); i != position.end(); position.next(i))
{
......
......@@ -22,8 +22,8 @@
* *
*******************************************************************************/
#include <boost/thread.hpp>
#include <boost/thread/barrier.hpp>
#include "Utils/threadbarrier.h"
#include <vector>
namespace CGoGN
......@@ -32,7 +32,7 @@ namespace CGoGN
template <typename T, unsigned int ORBIT, typename MAP>
inline void AttributeHandler<T, ORBIT, MAP>::registerInMap()
{
boost::mutex::scoped_lock lockAH(m_map->attributeHandlersMutex);
std::lock_guard<std::mutex> lockAH(m_map->attributeHandlersMutex);
m_map->attributeHandlers.insert(std::pair<AttributeMultiVectorGen*, AttributeHandlerGen*>(m_attrib, this)) ;
}
......@@ -41,7 +41,7 @@ inline void AttributeHandler<T, ORBIT, MAP>::unregisterFromMap()
{
typedef std::multimap<AttributeMultiVectorGen*, AttributeHandlerGen*>::iterator IT ;
boost::mutex::scoped_lock lockAH(m_map->attributeHandlersMutex);
std::lock_guard<std::mutex> lockAH(m_map->attributeHandlersMutex);
std::pair<IT, IT> bounds = m_map->attributeHandlers.equal_range(m_attrib) ;
for(IT i = bounds.first; i != bounds.second; ++i)
{
......@@ -276,13 +276,13 @@ class ThreadFunctionAttrib
{
protected:
std::vector<unsigned int>& m_ids;
boost::barrier& m_sync1;
boost::barrier& m_sync2;
Utils::Barrier& m_sync1;
Utils::Barrier& m_sync2;
bool& m_finished;
unsigned int m_id;
FUNC m_lambda;
public:
ThreadFunctionAttrib(FUNC func, std::vector<unsigned int>& vid, boost::barrier& s1, boost::barrier& s2, bool& finished, unsigned int id):
ThreadFunctionAttrib(FUNC func, std::vector<unsigned int>& vid, Utils::Barrier& s1, Utils::Barrier& s2, bool& finished, unsigned int id):
m_ids(vid), m_sync1(s1), m_sync2(s2), m_finished(finished), m_id(id), m_lambda(func)
{
}
......@@ -322,18 +322,18 @@ void foreach_attribute(ATTR& attribute, FUNC func, unsigned int nbthread)
nb++;
attribute.next(attIdx);
}
boost::barrier sync1(nbth+1);
boost::barrier sync2(nbth+1);
Utils::Barrier sync1(nbth+1);
Utils::Barrier sync2(nbth+1);
bool finished=false;
boost::thread** threads = new boost::thread*[nbth];
std::thread** threads = new std::thread*[nbth];
ThreadFunctionAttrib<FUNC>** tfs = new ThreadFunctionAttrib<FUNC>*[nbth];
for (unsigned int i = 0; i < nbth; ++i)
{
tfs[i] = new ThreadFunctionAttrib<FUNC>(func, vd[i], sync1,sync2,finished,i);
threads[i] = new boost::thread( boost::ref( *(tfs[i]) ) );
threads[i] = new std::thread( std::ref( *(tfs[i]) ) );
}
// and continue to traverse the map
......
......@@ -259,24 +259,27 @@ template <typename MAP, unsigned int CELL>
class CellMarkerStore: public CellMarkerBase<MAP, CELL>
{
protected:
std::vector<unsigned int> m_markedCells ;
std::vector<unsigned int>* m_markedCells ;
public:
CellMarkerStore(MAP& map, unsigned int thread = 0) :
CellMarkerBase<MAP, CELL>(map, thread)
{
m_markedCells.reserve(128);
// m_markedCells.reserve(128);
m_markedCells = GenericMap::askUIntBuffer(thread);
}
CellMarkerStore(const MAP& map, unsigned int thread = 0) :
CellMarkerBase<MAP, CELL>(map, thread)
{
m_markedCells.reserve(128);
// m_markedCells.reserve(128);
m_markedCells = GenericMap::askUIntBuffer(thread);
}
virtual ~CellMarkerStore()
{
unmarkAll() ;
GenericMap::releaseUIntBuffer(m_markedCells, this->m_thread);
// assert(isAllUnmarked);
// CGoGN_ASSERT(this->isAllUnmarked())
}
......@@ -290,20 +293,20 @@ public:
inline void mark(Cell<CELL> d)
{
CellMarkerBase<MAP, CELL>::mark(d) ;
m_markedCells.push_back(this->m_map.template getEmbedding<CELL>(d)) ;
m_markedCells->push_back(this->m_map.template getEmbedding<CELL>(d)) ;
}
inline void mark(unsigned int em)
{
CellMarkerBase<MAP, CELL>::mark(em) ;
m_markedCells.push_back(em) ;
m_markedCells->push_back(em) ;
}
inline void unmarkAll()
{
assert(this->m_markVector != NULL);
for (std::vector<unsigned int>::iterator it = m_markedCells.begin(); it != m_markedCells.end(); ++it)
for (std::vector<unsigned int>::iterator it = m_markedCells->begin(); it != m_markedCells->end(); ++it)
this->m_markVector->setFalse(*it);
}
};
......
......@@ -235,24 +235,26 @@ template <typename MAP>
class DartMarkerStore : public DartMarkerTmpl<MAP>
{
protected:
std::vector<unsigned int> m_markedDarts ;
std::vector<unsigned int>* m_markedDarts ;
public:
DartMarkerStore(MAP& map, unsigned int thread=0) :
DartMarkerTmpl<MAP>(map, thread)
{
m_markedDarts.reserve(128);
// m_markedDarts.reserve(128);
m_markedDarts = GenericMap::askUIntBuffer(thread);
}
DartMarkerStore(const MAP& map, unsigned int thread=0) :
DartMarkerTmpl<MAP>(map, thread)
{
m_markedDarts.reserve(128);
// m_markedDarts.reserve(128);
m_markedDarts = GenericMap::askUIntBuffer(thread);
}
virtual ~DartMarkerStore()
{
unmarkAll() ;
GenericMap::releaseUIntBuffer(m_markedDarts, this->m_thread);
// assert(isAllUnmarked) ;
// CGoGN_ASSERT(isAllUnmarked())
}
......@@ -268,7 +270,7 @@ public:
{
DartMarkerTmpl<MAP>::mark(d) ;
unsigned int d_index = this->m_map.dartIndex(d) ;
m_markedDarts.push_back(d_index) ;
m_markedDarts->push_back(d_index) ;
}
template <unsigned int ORBIT>
......@@ -278,13 +280,13 @@ public:
{
unsigned int d_index = this->m_map.dartIndex(d);
this->m_markVector->setTrue(d_index);
m_markedDarts.push_back(d_index);
m_markedDarts->push_back(d_index);
}) ;
}
inline void unmarkAll()
{
for (std::vector<unsigned int>::iterator it = m_markedDarts.begin(); it != m_markedDarts.end(); ++it)
for (std::vector<unsigned int>::iterator it = m_markedDarts->begin(); it != m_markedDarts->end(); ++it)
this->m_markVector->setFalse(*it);
}
} ;
......
......@@ -33,7 +33,6 @@
#include <list>
#include <vector>
#include <map>
#include <boost/thread/mutex.hpp>
#include "Container/attributeContainer.h"
#include "Container/fakeAttribute.h"
......@@ -43,7 +42,8 @@
#include "Topology/generic/marker.h"
#include "Topology/generic/functor.h"
#include <boost/thread.hpp>
#include <thread>
#include <mutex>
namespace CGoGN
{
......@@ -63,8 +63,8 @@ extern int NumberOfThreads;
inline int getSystemNumberOfCores(bool hyperthreading=false)
{
if (hyperthreading)
return boost::thread::hardware_concurrency()/2;
return boost::thread::hardware_concurrency();
return std::thread::hardware_concurrency()/2;
return std::thread::hardware_concurrency();
}
}
......@@ -98,6 +98,10 @@ protected:
static std::map<std::string, RegisteredBaseAttribute*>* m_attributes_registry_map;
static int m_nbInstances;
// TODO RELEASE MEMORY
static std::vector< std::vector<Dart>* > s_vdartsBuffers[NB_ORBITS];
static std::vector< std::vector<unsigned int>* > s_vintsBuffers[NB_ORBITS];
/**
* Direct access to the Dart attributes that store the orbits embeddings
* (only initialized when necessary, i.e. addEmbedding function)
......@@ -112,10 +116,8 @@ protected:
AttributeMultiVector<NoTypeNameAttribute<std::vector<Dart> > >* m_quickLocalIncidentTraversal[NB_ORBITS][NB_ORBITS] ;
AttributeMultiVector<NoTypeNameAttribute<std::vector<Dart> > >* m_quickLocalAdjacentTraversal[NB_ORBITS][NB_ORBITS] ;
// std::vector< AttributeMultiVector<MarkerBool>* > m_markVectors[NB_ORBITS] ;
std::vector< AttributeMultiVector<MarkerBool>* > m_markVectors_free[NB_ORBITS][NB_THREAD] ;
boost::mutex m_MarkerStorageMutex[NB_ORBITS];
std::mutex m_MarkerStorageMutex[NB_ORBITS];
/**
* Reserved boundary markers
......@@ -126,7 +128,7 @@ protected:
* Store links to created AttributeHandlers
*/
std::multimap<AttributeMultiVectorGen*, AttributeHandlerGen*> attributeHandlers ; // TODO think of MT (AttributeHandler creation & release are not thread safe!)
boost::mutex attributeHandlersMutex;
std::mutex attributeHandlersMutex;
// table of instancied maps for Dart/CellMarker release
static std::vector<GenericMap*> s_instances;
......@@ -146,6 +148,13 @@ public:
return false;
}
static inline std::vector<Dart>* askDartBuffer(unsigned int orbit);
static inline void releaseDartBuffer(std::vector<Dart>* vd, unsigned int orbit);
static inline std::vector<unsigned int>* askUIntBuffer(unsigned int orbit);
static inline void releaseUIntBuffer(std::vector<unsigned int>* vd, unsigned int orbit);
protected:
void init();
......
......@@ -28,6 +28,64 @@
namespace CGoGN
{
/****************************************
* BUFFERS MANAGEMENT *
****************************************/
inline std::vector<Dart>* GenericMap::askDartBuffer(unsigned int thread)
{
if (s_vdartsBuffers[thread].empty())
{
std::vector<Dart>* vd = new std::vector<Dart>;
vd->reserve(128);
return vd;
}
std::vector<Dart>* vd = s_vdartsBuffers[thread].back();
s_vdartsBuffers[thread].pop_back();
return vd;
}
inline void GenericMap::releaseDartBuffer(std::vector<Dart>* vd, unsigned int thread)
{
if (vd->capacity()>1024)
{
std::vector<Dart> v;
vd->swap(v);
vd->reserve(128);
}
vd->clear();
s_vdartsBuffers[thread].push_back(vd);
}
inline std::vector<unsigned int>* GenericMap::askUIntBuffer(unsigned int thread)
{
if (s_vintsBuffers[thread].empty())
{
std::vector<unsigned int>* vui = new std::vector<unsigned int>;
vui->reserve(128);
return vui;
}
std::vector<unsigned int>* vui = s_vintsBuffers[thread].back();
s_vintsBuffers[thread].pop_back();
return vui;
}
inline void GenericMap::releaseUIntBuffer(std::vector<unsigned int>* vui, unsigned int thread)
{
if (vui->capacity()>1024)
{
std::vector<unsigned int> v;
vui->swap(v);
vui->reserve(128);
}
vui->clear();
s_vintsBuffers[thread].push_back(vui);
}
/****************************************
* DARTS MANAGEMENT *
......@@ -167,7 +225,7 @@ AttributeMultiVector<MarkerBool>* GenericMap::askMarkVector(unsigned int thread)
}
else
{
boost::mutex::scoped_lock lockMV(m_MarkerStorageMutex[ORBIT]);
std::lock_guard<std::mutex> lockMV(m_MarkerStorageMutex[ORBIT]);
AttributeMultiVector<MarkerBool>* amv = m_attribs[ORBIT].addAttribute<MarkerBool>("") ;
return amv;
}
......
......@@ -22,8 +22,9 @@
* *
*******************************************************************************/
#include <boost/thread.hpp>
#include <boost/thread/barrier.hpp>
//#include <boost/thread.hpp>
//#include <boost/thread/barrier.hpp>
#include "Utils/threadbarrier.h"
#include <vector>
namespace CGoGN
......@@ -656,14 +657,14 @@ class ThreadFunction
protected:
typedef Cell<ORBIT> CELL;
std::vector<CELL>& m_cells;
boost::barrier& m_sync1;
boost::barrier& m_sync2;
Utils::Barrier& m_sync1;
Utils::Barrier& m_sync2;
bool& m_finished;
unsigned int m_id;
FUNC m_lambda;
public:
ThreadFunction(FUNC func, std::vector<CELL>& vd, boost::barrier& s1, boost::barrier& s2, bool& finished, unsigned int id):
ThreadFunction(FUNC func, std::vector<CELL>& vd, Utils::Barrier& s1, Utils::Barrier& s2, bool& finished, unsigned int id):
m_cells(vd), m_sync1(s1), m_sync2(s2), m_finished(finished), m_id(id), m_lambda(func)
{
}
......@@ -703,18 +704,18 @@ void foreach_cell_tmpl(MAP& map, FUNC func, unsigned int nbth)
nb++;
cell = trav.next();
}
boost::barrier sync1(nbth+1);
boost::barrier sync2(nbth+1);
Utils::Barrier sync1(nbth+1);
Utils::Barrier sync2(nbth+1);
bool finished=false;
// launch threads
boost::thread** threads = new boost::thread*[nbth];
std::thread** threads = new std::thread*[nbth];
ThreadFunction<ORBIT,FUNC>** tfs = new ThreadFunction<ORBIT,FUNC>*[nbth];
for (unsigned int i = 0; i < nbth; ++i)
{
tfs[i] = new ThreadFunction<ORBIT,FUNC>(func, vd[i],sync1,sync2, finished,1+i);
threads[i] = new boost::thread( boost::ref( *(tfs[i]) ) );
threads[i] = new std::thread( std::ref( *(tfs[i]) ) );
}
// and continue to traverse the map
......
......@@ -36,11 +36,16 @@ class TraversorDartsOfOrbit //: public Traversor<MAP>
{
private:
std::vector<Dart>::iterator m_current ;
std::vector<Dart> m_vd ;
std::vector<Dart>* m_vd ;
unsigned int m_thread;
TraversorDartsOfOrbit( const TraversorDartsOfOrbit<MAP,ORBIT>& /*tr*/){}
public:
TraversorDartsOfOrbit(const MAP& map, Cell<ORBIT> c, unsigned int thread = 0) ;
~TraversorDartsOfOrbit();
Dart begin() ;
Dart end() ;
......@@ -53,11 +58,16 @@ class VTraversorDartsOfOrbit : public Traversor
{
private:
std::vector<Dart>::iterator m_current ;
std::vector<Dart> m_vd ;
std::vector<Dart>* m_vd ;
unsigned int m_thread;
VTraversorDartsOfOrbit( const VTraversorDartsOfOrbit<MAP,ORBIT>& /*tr*/){}
public:
VTraversorDartsOfOrbit(const MAP& map, Cell<ORBIT> c, unsigned int thread = 0) ;
~VTraversorDartsOfOrbit();
Dart begin() ;
Dart end() ;
......
......@@ -29,17 +29,24 @@ namespace CGoGN
{
template <typename MAP, unsigned int ORBIT>
TraversorDartsOfOrbit<MAP, ORBIT>::TraversorDartsOfOrbit(const MAP& map, Cell<ORBIT> c, unsigned int thread)
TraversorDartsOfOrbit<MAP, ORBIT>::TraversorDartsOfOrbit(const MAP& map, Cell<ORBIT> c, unsigned int thread):
m_thread(thread)
{
m_vd.reserve(16);
map.foreach_dart_of_orbit(c, [&] (Dart d) { if (!map.isBoundaryMarkedCurrent(d)) m_vd.push_back(d); }, thread);
m_vd.push_back(NIL);
m_vd = GenericMap::askDartBuffer(thread);
map.foreach_dart_of_orbit(c, [&] (Dart d) { if (!map.isBoundaryMarkedCurrent(d)) m_vd->push_back(d); }, thread);
m_vd->push_back(NIL);
}
template <typename MAP, unsigned int ORBIT>
TraversorDartsOfOrbit<MAP, ORBIT>::~TraversorDartsOfOrbit()
{
GenericMap::releaseDartBuffer(m_vd, m_thread);
}
template <typename MAP, unsigned int ORBIT>
Dart TraversorDartsOfOrbit<MAP, ORBIT>::begin()
{
m_current = m_vd.begin();
m_current = m_vd->begin();
return *m_current;
}
......@@ -60,17 +67,24 @@ Dart TraversorDartsOfOrbit<MAP, ORBIT>::next()
template <typename MAP, unsigned int ORBIT>
VTraversorDartsOfOrbit<MAP, ORBIT>::VTraversorDartsOfOrbit(const MAP& map, Cell<ORBIT> c, unsigned int thread)
VTraversorDartsOfOrbit<MAP, ORBIT>::VTraversorDartsOfOrbit(const MAP& map, Cell<ORBIT> c, unsigned int thread):
m_thread(thread)
{
m_vd = GenericMap::askDartBuffer(thread);
map.foreach_dart_of_orbit(c, [&] (Dart d) { if (!map.isBoundaryMarkedCurrent(d)) m_vd->push_back(d); }, thread);
m_vd->push_back(NIL);
}
template <typename MAP, unsigned int ORBIT>
VTraversorDartsOfOrbit<MAP, ORBIT>::~VTraversorDartsOfOrbit()
{
m_vd.reserve(16);
map.foreach_dart_of_orbit(c, [&] (Dart d) { if (!map.isBoundaryMarkedCurrent(d)) m_vd.push_back(d); }, thread);
m_vd.push_back(NIL);
GenericMap::releaseDartBuffer(m_vd, m_thread);
}
template <typename MAP, unsigned int ORBIT>
Dart VTraversorDartsOfOrbit<MAP, ORBIT>::begin()
{
m_current = m_vd.begin();
m_current = m_vd->begin();
return *m_current;
}
......
......@@ -276,13 +276,13 @@ inline void ImplicitHierarchicalMap2::foreach_dart_of_volume(Dart d, FUNC& f, un
}
template <typename FUNC>
inline void ImplicitHierarchicalMap2::foreach_dart_of_vertex1(Dart d, FUNC& f, unsigned int thread) const
inline void ImplicitHierarchicalMap2::foreach_dart_of_vertex1(Dart d, FUNC& f, unsigned int /*thread*/) const
{
f(d);
}
template <typename FUNC>
inline void ImplicitHierarchicalMap2::foreach_dart_of_edge1(Dart d, FUNC& f, unsigned int thread) const
inline void ImplicitHierarchicalMap2::foreach_dart_of_edge1(Dart d, FUNC& f, unsigned int /*thread*/) const
{
f(d);
}
......
......@@ -21,6 +21,8 @@
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __SNAPSHOT_HD__
#define __SNAPSHOT_HD__
#include <QImage>
#include <GL/glew.h>
......@@ -129,3 +131,5 @@ void SnapshotHD::unbind()
}
}
#endif
/*******************************************************************************
* 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 __BARRIER_THREAD__
#define __BARRIER_THREAD__
#include <thread>
#include <mutex>
#include <condition_variable>
namespace CGoGN
{
namespace Utils
{
/**
* Implementation of simple counter barrier (rdv)
* for std::thread of c++11
*/
class Barrier
{
private:
unsigned int m_initCount;
unsigned int m_count;
unsigned int m_generation;
std::mutex m_protect;
std::condition_variable m_cond;
public:
/**
* constructor
* @param count number of threads to syncronize
*/
inline Barrier(unsigned int count):
m_initCount(count), m_count(count), m_generation(0) {}
inline bool wait()
{
std::unique_lock<std::mutex> lock(m_protect);
unsigned int gen = m_generation;
if (--m_count == 0)
{
m_generation++;
m_count = m_initCount;
m_cond.notify_all();
return true;
}
while (gen == m_generation)
m_cond.wait(lock);
return false;
}
};
}
}
#endif
......@@ -30,6 +30,8 @@
#include "Geometry/matrix.h"
#include "Container/registered.h"
#include <algorithm>
namespace CGoGN
{
......@@ -42,6 +44,11 @@ int NumberOfThreads = getSystemNumberOfCores();
std::map<std::string, RegisteredBaseAttribute*>* GenericMap::m_attributes_registry_map = NULL;
int GenericMap::m_nbInstances = 0;
std::vector< std::vector<Dart>* > GenericMap::s_vdartsBuffers[NB_ORBITS];
std::vector< std::vector<unsigned int>* > GenericMap::s_vintsBuffers[NB_ORBITS];
// table of instancied maps for Dart/CellMarker release
std::vector<GenericMap*> GenericMap::s_instances;
......@@ -83,6 +90,8 @@ GenericMap::GenericMap()
registerAttribute<Geom::Matrix44d>(Geom::Matrix44d::CGoGNnameOfType());
}
m_nbInstances++;
s_instances.push_back(this);
......@@ -92,10 +101,16 @@ GenericMap::GenericMap()
m_attribs[i].setRegistry(m_attributes_registry_map) ;
}
for(unsigned int i = 0; i < NB_THREAD; ++i)
{
if (s_vdartsBuffers[i].capacity()<8)
{
s_vdartsBuffers[i].reserve(8);
s_vintsBuffers[i].reserve(8);
// prealloc ?
}
}
init();
// boundary markers dans init ou ici ?