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