J
Jim West
I'm curious why I might be getting such a large performance
difference between using a map iterator and a vector iterator.
This is a computational electromagnetics code where I have to
separate points in space that arrive randomly into groupings
based on (x, y, z) dimensions, so I use std::map to do that.
Once the sorting is done I need to find the interactions between
groups, so I've been using iterators to step through the map.
As a test, I then modified the code a bit to first copy the
groups from the map into a vector so I could use a vector
iterator. I didn't expect any significant performance difference
since there are heavy floating point calculations going on at
each step. However, with Intel C++ 7.1 the compuation time to do
the nested loops below decreased from 78.5 seconds to 60 seconds
when I switched to the vector. The difference with GCC was less
severe, but it still decreased from 81.5 seconds with the map to
73.1 seconds with the vector.
My question is why there is such a dramatic difference in
these two cases. With all the floating point calculations going
on, I can't imagine that the actual time to increment the
iterators is having an effect. Could the map template be
preventing optimizations that the vector template alone
permits? (I used -O3 optimization in both cases.) Is this
a typical penalty paid when iterating through a map instead
of a vector?
Code sample with map or vector implementation chosen using
#define statements. Note that I added the pointers to the map
elements to allow the same code to be used below with either
iterator. This had no effect on the execution time.
using namespace std;
typedef map<DIMS<int> , GROUP> GROUP_MAP; // DIMS has x, y, z indices
vector<GROUP_MAP> groups_map;
#ifdef USE_GROUPS_VECTOR
typedef vector<GROUP> GROUP_VECTOR;
vector<GROUP_VECTOR> groups_vector;
.... // Copy groups from map to vector
#endif
for (int level = 0; level < LEVELS; ++level) {
#ifdef USE_GROUPS_MAP // Slower
for (GROUP_MAP::iterator M_it = groups_map[level].begin();
M_it != groups_map[level].end(); ++M_it) {
GROUP *m_group = &(M_it->second); // For compatibility below
for (GROUP_MAP::iterator N_it = groups_map[level].begin();
N_it != groups_map[level].end(); ++N_it) {
GROUP *n_group = &(N_it->second); // For compatibility below
#endif
#ifdef USE_GROUPS_VECTOR // Faster
for (GROUP_VECTOR::iterator m_group = groups_vector[level].begin();
m_group != groups_vector[level].end(); ++m_group) {
for (GROUP_VECTOR::iterator n_group = groups_vector[level].begin();
n_group != groups_vector[level].end(); ++n_group) {
#endif
... // Heavy floating-point calculations, calling Fortran/C libraries
}
}
}
difference between using a map iterator and a vector iterator.
This is a computational electromagnetics code where I have to
separate points in space that arrive randomly into groupings
based on (x, y, z) dimensions, so I use std::map to do that.
Once the sorting is done I need to find the interactions between
groups, so I've been using iterators to step through the map.
As a test, I then modified the code a bit to first copy the
groups from the map into a vector so I could use a vector
iterator. I didn't expect any significant performance difference
since there are heavy floating point calculations going on at
each step. However, with Intel C++ 7.1 the compuation time to do
the nested loops below decreased from 78.5 seconds to 60 seconds
when I switched to the vector. The difference with GCC was less
severe, but it still decreased from 81.5 seconds with the map to
73.1 seconds with the vector.
My question is why there is such a dramatic difference in
these two cases. With all the floating point calculations going
on, I can't imagine that the actual time to increment the
iterators is having an effect. Could the map template be
preventing optimizations that the vector template alone
permits? (I used -O3 optimization in both cases.) Is this
a typical penalty paid when iterating through a map instead
of a vector?
Code sample with map or vector implementation chosen using
#define statements. Note that I added the pointers to the map
elements to allow the same code to be used below with either
iterator. This had no effect on the execution time.
using namespace std;
typedef map<DIMS<int> , GROUP> GROUP_MAP; // DIMS has x, y, z indices
vector<GROUP_MAP> groups_map;
#ifdef USE_GROUPS_VECTOR
typedef vector<GROUP> GROUP_VECTOR;
vector<GROUP_VECTOR> groups_vector;
.... // Copy groups from map to vector
#endif
for (int level = 0; level < LEVELS; ++level) {
#ifdef USE_GROUPS_MAP // Slower
for (GROUP_MAP::iterator M_it = groups_map[level].begin();
M_it != groups_map[level].end(); ++M_it) {
GROUP *m_group = &(M_it->second); // For compatibility below
for (GROUP_MAP::iterator N_it = groups_map[level].begin();
N_it != groups_map[level].end(); ++N_it) {
GROUP *n_group = &(N_it->second); // For compatibility below
#endif
#ifdef USE_GROUPS_VECTOR // Faster
for (GROUP_VECTOR::iterator m_group = groups_vector[level].begin();
m_group != groups_vector[level].end(); ++m_group) {
for (GROUP_VECTOR::iterator n_group = groups_vector[level].begin();
n_group != groups_vector[level].end(); ++n_group) {
#endif
... // Heavy floating-point calculations, calling Fortran/C libraries
}
}
}