
I am having great difficulty in architecting my boost serialization solution with the Intel compiler. The problem is this: I need to support text, xml, and binary archive formats. I allow the user to select which format to save in, by default using the portable text format. If the user wants greater speed, they can choose binary, or if they want to visually inspect the data, they can choose xml. On load, I dynamically detect which archive is used and call the appropriate load routine (text, xml, binary). However, if I include all three archives in the same compilation unit, the default (text) serialization is slowed down dramatically, with the runtimes increasing approximately 50% (from 200 to 300 seconds, and this on a fast 64-bit Opteron box). I tried breaking things apart, putting my archive includes and BOOST_CLASS_EXPORT calls into separate compilation units. I have the following code structure: class AbstractBase { virtual void method() = 0; }; BOOST_IS_ABSTRACT(AbstractBase) class Derived: public AbstractBase { virtual void method() {} }; class A { Def* def; template <class Archvie> void serialize(Archive& ar, const unsigned int version) { ar & def; } }; I break my serialization code into three different files, one for each type of archive, each of which includes a common file that has a templated method for loading a serialized file, along with BOOST_CLASS_EXPORT for the derived class. Here is the text version: #include <boost/archive/text_oarchive.hpp> #include "Serialization.hh" A* BoostTextLoader::load() { return Serialization<text_iarchive>::load(fileName); } #include <boost/serialization/export.hpp> BOOST_CLASS_EXPORT(Derived) Here is the binary: #include <boost/archive/binary_oarchive.hpp> #include "Serialization.hh" A* BoostTextLoader::load() { return Serialization<binary_iarchive>::load(fileName); } #include <boost/serialization/export.hpp> BOOST_CLASS_EXPORT(Derived) and a similar one for XML. The Serialization.hh is roughly this: template<typename Archive> struct FanSerialization { static A* load(const std::string& filename) { A* a = 0; stream<mapped_file_source> ifs(filename); Archive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(a); return a; } } When I compile and try to link a test program, I get errors saying "multiple definition of `boost::archive::detail::guid_initializer<Derived>::instance'" and so on. So, I try removing the BOOST_CLASS export from the binary and XML code modules, leaving it in the text version. Compile and link are now good. The text archive performance is back down to 200 seconds. When I try to serialize binary (or xml) archives, I get. /boost-1_33_1/boost/archive/detail/oserializer.hpp:418: static void boost::archive::detail::save_pointer_type<Archive, TPtr>::polymorphic<T>::save(Archive &, const T &, const boost::archive::detail::basic_pointer_oserializer *) [with T = AbstractBase, Archive = boost::archive::xml_oarchive, TPtr = AbstractBase*]: Assertion `0L != bpos_ptr' failed. The code that is failing is from the assert below (oserializer.hpp): // sice true_type is valid, and this only gets made if the // pointer oserializer object has been created, this should never // fail bpos_ptr = archive_pointer_oserializer<Archive>::find(* true_type); assert(NULL != bpos_ptr); if(NULL == bpos_ptr) boost::throw_exception( archive_exception(archive_exception::unregistered_class) ); ar.save_pointer(vp, bpos_ptr); So, needless to say, I'm a bit confused by what is going on. Is there any way at all to fix this? I have run a profiler on the Intel code and it simply seems to be "doing more" than the non-Intel version (more comparison operators, chiefly). Could there be any way to manually instantiate things, or substitute the containers boost uses for look-ups at run-time with different, separate ones? Thanks. Bill