From 2d6d23849a88bdac83407370128d0bc53d6aff2b Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Thu, 1 Nov 2012 13:45:14 +0000 Subject: [PATCH] Some performance issues, part II. --- AMDiS/src/parallel/ElementObjectDatabase.cc | 53 ++++++++++----------- AMDiS/src/parallel/ElementObjectDatabase.h | 33 +++++++------ AMDiS/src/parallel/InteriorBoundary.cc | 18 +++---- 3 files changed, 53 insertions(+), 51 deletions(-) diff --git a/AMDiS/src/parallel/ElementObjectDatabase.cc b/AMDiS/src/parallel/ElementObjectDatabase.cc index 843954ec..92f5ef04 100644 --- a/AMDiS/src/parallel/ElementObjectDatabase.cc +++ b/AMDiS/src/parallel/ElementObjectDatabase.cc @@ -179,6 +179,7 @@ namespace AMDiS { } } + void ElementObjectDatabase::addVertex(Element *el, int ith) { DegreeOfFreedom vertex = el->getDof(ith, 0); @@ -796,7 +797,7 @@ namespace AMDiS { nSize = vertexLocalMap.size(); SerUtil::serialize(out, nSize); - for (map<ElementObjectData, DegreeOfFreedom>::iterator it = vertexLocalMap.begin(); + for (boost::container::flat_map<ElementObjectData, DegreeOfFreedom>::iterator it = vertexLocalMap.begin(); it != vertexLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); @@ -804,7 +805,7 @@ namespace AMDiS { nSize = edgeLocalMap.size(); SerUtil::serialize(out, nSize); - for (map<ElementObjectData, DofEdge>::iterator it = edgeLocalMap.begin(); + for (boost::container::flat_map<ElementObjectData, DofEdge>::iterator it = edgeLocalMap.begin(); it != edgeLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); @@ -812,7 +813,7 @@ namespace AMDiS { nSize = faceLocalMap.size(); SerUtil::serialize(out, nSize); - for (map<ElementObjectData, DofFace>::iterator it = faceLocalMap.begin(); + for (boost::container::flat_map<ElementObjectData, DofFace>::iterator it = faceLocalMap.begin(); it != faceLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); @@ -821,7 +822,7 @@ namespace AMDiS { nSize = vertexInRank.size(); SerUtil::serialize(out, nSize); - for (map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator it = vertexInRank.begin(); + for (flat_map<DegreeOfFreedom, flat_map<int, ElementObjectData> >::iterator it = vertexInRank.begin(); it != vertexInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -829,7 +830,7 @@ namespace AMDiS { nSize = edgeInRank.size(); SerUtil::serialize(out, nSize); - for (map<DofEdge, map<int, ElementObjectData> >::iterator it = edgeInRank.begin(); + for (flat_map<DofEdge, flat_map<int, ElementObjectData> >::iterator it = edgeInRank.begin(); it != edgeInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -837,7 +838,7 @@ namespace AMDiS { nSize = faceInRank.size(); SerUtil::serialize(out, nSize); - for (map<DofFace, map<int, ElementObjectData> >::iterator it = faceInRank.begin(); + for (flat_map<DofFace, flat_map<int, ElementObjectData> >::iterator it = faceInRank.begin(); it != faceInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -957,7 +958,7 @@ namespace AMDiS { vertexInRank.clear(); for (int i = 0; i < nSize; i++) { DegreeOfFreedom dof; - map<int, ElementObjectData> data; + flat_map<int, ElementObjectData> data; SerUtil::deserialize(in, dof); deserialize(in, data); vertexInRank[dof] = data; @@ -967,7 +968,7 @@ namespace AMDiS { edgeInRank.clear(); for (int i = 0; i < nSize; i++) { DofEdge edge; - map<int, ElementObjectData> data; + flat_map<int, ElementObjectData> data; SerUtil::deserialize(in, edge); deserialize(in, data); edgeInRank[edge] = data; @@ -977,7 +978,7 @@ namespace AMDiS { faceInRank.clear(); for (int i = 0; i < nSize; i++) { DofFace face; - map<int, ElementObjectData> data; + flat_map<int, ElementObjectData> data; SerUtil::deserialize(in, face); deserialize(in, data); faceInRank[face] = data; @@ -1055,11 +1056,11 @@ namespace AMDiS { void ElementObjectDatabase::serialize(ostream &out, - map<int, ElementObjectData>& data) + flat_map<int, ElementObjectData>& data) { int nSize = data.size(); SerUtil::serialize(out, nSize); - for (map<int, ElementObjectData>::iterator it = data.begin(); + for (flat_map<int, ElementObjectData>::iterator it = data.begin(); it != data.end(); ++it) { SerUtil::serialize(out, it->first); it->second.serialize(out); @@ -1068,7 +1069,7 @@ namespace AMDiS { void ElementObjectDatabase::deserialize(istream &in, - map<int, ElementObjectData>& data) + flat_map<int, ElementObjectData>& data) { int nSize; SerUtil::deserialize(in, nSize); @@ -1093,6 +1094,7 @@ namespace AMDiS { const unsigned int faceSize = sizeof(DofFace); const unsigned int vectorOverhead = sizeof(vector<int>); const unsigned int mapOverhead = 48; //sizeof(_Rb_tree<int, int>); + const unsigned int flatMapOverhead = 24; const unsigned int mapEntryOverhead = 40; // sizeof(_Rb_tree_node_base); const unsigned int setOverhead = 48; const unsigned int setEntryOverhead = 40; @@ -1127,41 +1129,38 @@ namespace AMDiS { tmp = 0; // vertexLocalMap - tmp += mapOverhead + vertexLocalMap.size() * (mapEntryOverhead + structElObjDataSize + dofSize); + tmp += flatMapOverhead + vertexLocalMap.size() * (structElObjDataSize + dofSize); // edgeLocalMap - tmp += mapOverhead + edgeLocalMap.size() * (mapEntryOverhead + structElObjDataSize + edgeSize); + tmp += flatMapOverhead + edgeLocalMap.size() * (structElObjDataSize + edgeSize); // faceLocalMap - tmp += mapOverhead + faceLocalMap.size() * (mapEntryOverhead + structElObjDataSize + faceSize); + tmp += flatMapOverhead + faceLocalMap.size() * (structElObjDataSize + faceSize); MSG("EL-OBJ-DB MEM 04: %d\n", tmp); value += tmp; // vertexInRank - tmp = mapOverhead + vertexInRank.size() * mapEntryOverhead; - for (map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator mapIt = + tmp = flatMapOverhead; + for (flat_map<DegreeOfFreedom, flat_map<int, ElementObjectData> >::iterator mapIt = vertexInRank.begin(); mapIt != vertexInRank.end(); ++mapIt) - tmp += dofSize + mapOverhead + - mapIt->second.size() * (mapEntryOverhead + sizeof(int) + structElObjDataSize); + tmp += dofSize + flatMapOverhead + mapIt->second.size() * (sizeof(int) + structElObjDataSize); MSG("EL-OBJ-DB MEM 05: %d\n", tmp); value += tmp; // edgeInRank - tmp += mapOverhead + edgeInRank.size() * mapEntryOverhead; - for (map<DofEdge, map<int, ElementObjectData> >::iterator mapIt = + tmp = mapOverhead; + for (flat_map<DofEdge, flat_map<int, ElementObjectData> >::iterator mapIt = edgeInRank.begin(); mapIt != edgeInRank.end(); ++mapIt) - tmp += edgeSize + mapOverhead + - mapIt->second.size() * (mapEntryOverhead + sizeof(int) + structElObjDataSize); + tmp += edgeSize + flatMapOverhead + mapIt->second.size() * (sizeof(int) + structElObjDataSize); MSG("EL-OBJ-DB MEM 06: %d\n", tmp); value += tmp; // faceInRank - tmp = mapOverhead + faceInRank.size() * mapEntryOverhead; - for (map<DofFace, map<int, ElementObjectData> >::iterator mapIt = + tmp = mapOverhead; + for (flat_map<DofFace, flat_map<int, ElementObjectData> >::iterator mapIt = faceInRank.begin(); mapIt != faceInRank.end(); ++mapIt) - tmp += faceSize + mapOverhead + - mapIt->second.size() * (mapEntryOverhead + sizeof(int) + structElObjDataSize); + tmp += faceSize + flatMapOverhead + mapIt->second.size() * (sizeof(int) + structElObjDataSize); MSG("EL-OBJ-DB MEM 07: %d\n", tmp); value += tmp; tmp = 0; diff --git a/AMDiS/src/parallel/ElementObjectDatabase.h b/AMDiS/src/parallel/ElementObjectDatabase.h index 3bec6945..3242be7a 100644 --- a/AMDiS/src/parallel/ElementObjectDatabase.h +++ b/AMDiS/src/parallel/ElementObjectDatabase.h @@ -27,6 +27,7 @@ #include <vector> #include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple_comparison.hpp> +#include <boost/container/flat_map.hpp> #include "AMDiS_fwd.h" #include "Containers.h" @@ -39,6 +40,8 @@ namespace AMDiS { using namespace std; + using boost::container::flat_map; + /// Just to templatize the typedef. template<typename T> struct PerBoundMap { @@ -210,7 +213,7 @@ namespace AMDiS { /// Returns the data of the current iterator position. - map<int, ElementObjectData>& getIterateData() + flat_map<int, ElementObjectData>& getIterateData() { switch (iterGeoPos) { case VERTEX: @@ -315,7 +318,7 @@ namespace AMDiS { /// the vertex, the element with the highest element index is given. If the /// vertex is not contained in a rank's subdomain, it will not be considered /// in this mapping. - map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex) + flat_map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex) { return vertexInRank[vertex]; } @@ -326,7 +329,7 @@ namespace AMDiS { /// the edge, the element with the highest element index is given. If the /// edge is not contained in a rank's subdomain, it will not be considered /// in this mapping. - map<int, ElementObjectData>& getElementsInRank(DofEdge edge) + flat_map<int, ElementObjectData>& getElementsInRank(DofEdge edge) { return edgeInRank[edge]; } @@ -335,7 +338,7 @@ namespace AMDiS { /// element data objects, which identify on the rank the element which /// contains this face. If the face is not contained in a rank's subdomain, /// it will not be considered in this mapping. - map<int, ElementObjectData>& getElementsInRank(DofFace face) + flat_map<int, ElementObjectData>& getElementsInRank(DofFace face) { return faceInRank[face]; } @@ -483,10 +486,10 @@ namespace AMDiS { void deserialize(istream &in, vector<ElementObjectData>& elVec); /// Some auxiliary function to write the element object database to disk. - void serialize(ostream &out, map<int, ElementObjectData>& data); + void serialize(ostream &out, flat_map<int, ElementObjectData>& data); /// Some auxiliary function to read the element object database from disk. - void deserialize(istream &in, map<int, ElementObjectData>& data); + void deserialize(istream &in, flat_map<int, ElementObjectData>& data); int getOwner(vector<ElementObjectData>& objData, int level); private: @@ -507,36 +510,36 @@ namespace AMDiS { /// Maps to an element object the corresponding vertex DOF. - map<ElementObjectData, DegreeOfFreedom> vertexLocalMap; + flat_map<ElementObjectData, DegreeOfFreedom> vertexLocalMap; /// Maps to an element object the corresponding edge. - map<ElementObjectData, DofEdge> edgeLocalMap; + flat_map<ElementObjectData, DofEdge> edgeLocalMap; /// Maps to an element object the corresponding face. - map<ElementObjectData, DofFace> faceLocalMap; + flat_map<ElementObjectData, DofFace> faceLocalMap; /// Defines to each vertex DOF a map that maps to each rank number the element /// objects that have this vertex DOF in common. - map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank; + flat_map<DegreeOfFreedom, flat_map<int, ElementObjectData> > vertexInRank; /// Defines to each edge a map that maps to each rank number the element /// objects that have this edge in common. - map<DofEdge, map<int, ElementObjectData> > edgeInRank; + flat_map<DofEdge, flat_map<int, ElementObjectData> > edgeInRank; /// Defines to each face a map that maps to each rank number the element /// objects that have this face in common. - map<DofFace, map<int, ElementObjectData> > faceInRank; + flat_map<DofFace, flat_map<int, ElementObjectData> > faceInRank; /// Vertex iterator to iterate over \ref vertexInRank - map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter; + flat_map<DegreeOfFreedom, flat_map<int, ElementObjectData> >::iterator vertexIter; /// Edge iterator to iterate over \ref edgeInRank - map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter; + flat_map<DofEdge, flat_map<int, ElementObjectData> >::iterator edgeIter; /// Face iterator to iterate over \ref faceInRank - map<DofFace, map<int, ElementObjectData> >::iterator faceIter; + flat_map<DofFace, flat_map<int, ElementObjectData> >::iterator faceIter; /// Defines the geometrical iteration index of the iterators. I.e., the value diff --git a/AMDiS/src/parallel/InteriorBoundary.cc b/AMDiS/src/parallel/InteriorBoundary.cc index 24243fb0..8eee4cd5 100644 --- a/AMDiS/src/parallel/InteriorBoundary.cc +++ b/AMDiS/src/parallel/InteriorBoundary.cc @@ -49,7 +49,7 @@ namespace AMDiS { GeoIndex geoIndex = INDEX_OF_DIM(geoPos, mesh->getDim()); while (elObjDb.iterate(geoIndex)) { - map<int, ElementObjectData>& objData = elObjDb.getIterateData(); + flat_map<int, ElementObjectData>& objData = elObjDb.getIterateData(); // Test, if this is a boundary object of this rank. if (!(objData.count(globalMpiRank) && objData.size() > 1)) @@ -61,7 +61,7 @@ namespace AMDiS { if (allRanks) { boundaryWithinMpiGroup = true; } else { - for (map<int, ElementObjectData>::iterator it = objData.begin(); + for (flat_map<int, ElementObjectData>::iterator it = objData.begin(); it != objData.end(); ++it) { if (it->first != globalMpiRank && levelRanks.count(it->first)) { boundaryWithinMpiGroup = true; @@ -95,7 +95,7 @@ namespace AMDiS { if (owner == globalMpiRank) { - for (map<int, ElementObjectData>::iterator it2 = objData.begin(); + for (flat_map<int, ElementObjectData>::iterator it2 = objData.begin(); it2 != objData.end(); ++it2) { if (it2->first == globalMpiRank) continue; @@ -162,7 +162,7 @@ namespace AMDiS { ElementObjectData& perDofEl0 = elObjDb.getElementsInRank(it->first.first)[globalMpiRank]; - for (map<int, ElementObjectData>::iterator elIt = elObjDb.getElementsInRank(it->first.second).begin(); + for (flat_map<int, ElementObjectData>::iterator elIt = elObjDb.getElementsInRank(it->first.second).begin(); elIt != elObjDb.getElementsInRank(it->first.second).end(); ++elIt) { int otherElementRank = elIt->first; @@ -185,7 +185,7 @@ namespace AMDiS { if (removePeriodicBoundary) { bound.type = INTERIOR; - map<int, ElementObjectData> objData = + flat_map<int, ElementObjectData> objData = elObjDb.getElementsInRank(it->first.first); objData.insert(elObjDb.getElementsInRank(it->first.second).begin(), elObjDb.getElementsInRank(it->first.second).end()); @@ -255,7 +255,7 @@ namespace AMDiS { ElementObjectData& perEdgeEl0 = elObjDb.getElementsInRank(it->first.first)[globalMpiRank]; - for (map<int, ElementObjectData>::iterator elIt = elObjDb.getElementsInRank(it->first.second).begin(); + for (flat_map<int, ElementObjectData>::iterator elIt = elObjDb.getElementsInRank(it->first.second).begin(); elIt != elObjDb.getElementsInRank(it->first.second).end(); ++elIt) { int otherElementRank = elIt->first; @@ -277,7 +277,7 @@ namespace AMDiS { if (removePeriodicBoundary) { bound.type = INTERIOR; - map<int, ElementObjectData> objData = + flat_map<int, ElementObjectData> objData = elObjDb.getElementsInRank(it->first.first); objData.insert(elObjDb.getElementsInRank(it->first.second).begin(), elObjDb.getElementsInRank(it->first.second).end()); @@ -337,7 +337,7 @@ namespace AMDiS { ElementObjectData& perFaceEl0 = elObjDb.getElementsInRank(it->first.first)[globalMpiRank]; - for (map<int, ElementObjectData>::iterator elIt = elObjDb.getElementsInRank(it->first.second).begin(); + for (flat_map<int, ElementObjectData>::iterator elIt = elObjDb.getElementsInRank(it->first.second).begin(); elIt != elObjDb.getElementsInRank(it->first.second).end(); ++elIt) { int otherElementRank = elIt->first; @@ -359,7 +359,7 @@ namespace AMDiS { if (removePeriodicBoundary) { bound.type = INTERIOR; - map<int, ElementObjectData> objData = + flat_map<int, ElementObjectData> objData = elObjDb.getElementsInRank(it->first.first); objData.insert(elObjDb.getElementsInRank(it->first.second).begin(), elObjDb.getElementsInRank(it->first.second).end()); -- GitLab