This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
BOOST_FOREACH less efficient than handcoded loop for some testcases
- From: Erik <sigra at home dot se>
- To: gcc-help at gcc dot gnu dot org
- Date: Thu, 11 Oct 2007 14:44:32 +0200
- Subject: BOOST_FOREACH less efficient than handcoded loop for some testcases
I made some tests of BOOST_FOREACH (from boost-1.34) to see if it
generates as good code as a handcoded loop. The answer is that it does
under certain circumstances. I tested g++-4.2.0 and g++-4.1.2 and the
optimizations levels O3, O2 and Os. Here is the first testcase (where a
reference to the vector is passed as a parameter):
//////////////////////////////////////////////////////////////////////////////
void f(float);
#include <boost/foreach.hpp>
#include <vector>
void g(const std::vector<float> & v) {
BOOST_FOREACH(float i, v)
f(i);
}
//////////////////////////////////////////////////////////////////////////////
This is as efficient as a handcoded loop if and only if the g++ version is 4.2.0 and the optimization level is O3. There will be 21 assembly instructions.
Here is the other testcase:
//////////////////////////////////////////////////////////////////////////////
void f(float);
#include <boost/foreach.hpp>
#include <vector>
struct A {
void g() const;
char name[52];
std::vector<float> const v;
};
void A::g() const {
BOOST_FOREACH(float i, v)
f(i);
}
//////////////////////////////////////////////////////////////////////////////
Unfortunately this gives as much as 24 instructions, while then handcoded version still gives only 21 instructions.
I attach the script I used for testing. If you want to try it yourself, put the script in an empty directory and run from there; it will create some files. After running it, it may be interesting to compare the generated code, for example:
diff -dU2 iterate_vector-member-g++-4.2.0-O3.s BOOST_FOREACH-member-g++-4.2.0-O3.s|kompare -
Can gcc be fixed so that it optimizes BOOST_FOREACH to be as efficient as a handcoded loop? Should I report it to the bugtracker?
#! /bin/sh
ITERATIONS="0 1 2"
ITERATION_NAMES=(handcoded iterate_vector BOOST_FOREACH)
ITERATION_CODES=(\
"
std::vector<float>::const_iterator const v_end = v.end();
for (std::vector<float>::const_iterator it = v.begin(); it != v_end; ++it)
f(*it);" \
"
#define iterate_vector_const(value_type, it, v) \\
for \\
(struct { \\
std::vector<value_type>::const_iterator current; \\
std::vector<value_type>::const_iterator const end; \\
value_type const & operator*() {return *current;} \\
} it = {v.begin(), v.end()}; \\
it.current != it.end; \\
++it.current) \\
iterate_vector_const(float, it, v)
f(*it);" \
"
BOOST_FOREACH(float i, v)
f(i);")
EXAMPLES="0 1 2"
EXAMPLE_NAMES=(parameter member member_with_local)
EXAMPLE_CODES=(\
"
void g(const std::vector<float> & v) {" \
"
struct A {
void g() const;
char name[52];
std::vector<float> const v;
};
void A::g() const {" \
"
struct A {
void g() const;
char name[52];
std::vector<float> const m_v;
};
void A::g() const {
std::vector<float> const & v = m_v;
")
COMPILER_VERSIONS="4.2.0 4.1.2"
OPTIMIZATOINS="3 2 s"
unset TABLE_HEADER
for optimization in $OPTIMIZATOINS; do
TABLE_HEADER="$TABLE_HEADER O$optimization"
done
echo "Optimizations: $TABLE_HEADER"
for iteration in $ITERATIONS; do
echo ${ITERATION_NAMES[$iteration]}:
for example in $EXAMPLES; do
NAME=${ITERATION_NAMES[$iteration]}-${EXAMPLE_NAMES[$example]}
IN=$NAME.cc
rm -f $IN
echo "void f(float);" >> $IN
echo "#include <boost/foreach.hpp>" >> $IN
echo "#include <vector>" >> $IN
echo "${EXAMPLE_CODES[$example]}" >> $IN
echo "${ITERATION_CODES[$iteration]}" >> $IN
echo "}" >> $IN
echo " ${EXAMPLE_NAMES[$example]}:"
for compiler_version in $COMPILER_VERSIONS; do
MESSAGE=g++-$compiler_version:
for optimization in $OPTIMIZATOINS; do
OUT=$NAME-g++-$compiler_version-O$optimization.s
g++-$compiler_version -Wall -Wextra -O$optimization -S $IN -o $OUT
MESSAGE="$MESSAGE $(egrep -v "^([ ]*\\.|_)" $OUT|wc -l)"
done
echo " $MESSAGE"
done
done
done