Boost logo

Boost Users :

Subject: Re: [Boost-users] [serialization] Runtime overhead of serialization archives
From: Ernest Zaslavsky (ernest.zaslavsky_at_[hidden])
Date: 2016-09-25 04:56:11


>> have you run my code from the post at 23.9.16 19:41 (make_array)?
Yep

And here results for your latest code. Looks like it is doing quite well.

Run on (8 X 3392 MHz CPU s)
09/25/16 11:50:14
Benchmark Time CPU Iterations
------------------------------------------------------------
to_wire_xml/8 30685 ns 30594 ns 22436 255.361kB/s
to_wire_xml/64 33922 ns 34315 ns 21367 1.77868MB/s
to_wire_xml/512 59209 ns 59797 ns 11218 8.16563MB/s
to_wire_xml/4k 253341 ns 255922 ns 2804 15.2635MB/s
to_wire_xml/32k 1831131 ns 1793594 ns 374 17.4231MB/s
to_wire_xml/256k 14493601 ns 14352092 ns 50 17.4191MB/s
to_wire_xml/2M 116950902 ns 117000750 ns 6 17.0939MB/s
to_wire_xml/4M 237862928 ns 234001500 ns 3 17.0939MB/s
from_wire_xml/8 38244 ns 38242 ns 17949 204.291kB/s
from_wire_xml/64 42733 ns 42831 ns 16026 1.42503MB/s
from_wire_xml/512 80459 ns 81703 ns 8974 5.97628MB/s
from_wire_xml/4k 362877 ns 359818 ns 1951 10.8562MB/s
from_wire_xml/32k 2637410 ns 2600017 ns 264 12.0192MB/s
from_wire_xml/256k 20917089 ns 20962634 ns 32 11.926MB/s
from_wire_xml/2M 166986547 ns 163801050 ns 4 12.2099MB/s
from_wire_xml/4M 334816819 ns 335402150 ns 2 11.926MB/s
to_wire_text/8 12291 ns 12412 ns 64102 629.454kB/s
to_wire_text/64 15434 ns 15645 ns 44872 3.90136MB/s
to_wire_text/512 39425 ns 39773 ns 17258 12.2767MB/s
to_wire_text/4k 231714 ns 233668 ns 2804 16.7171MB/s
to_wire_text/32k 1831865 ns 1835306 ns 408 17.0271MB/s
to_wire_text/256k 14413837 ns 14213424 ns 45 17.589MB/s
to_wire_text/2M 115013254 ns 114400733 ns 6 17.4824MB/s
to_wire_text/4M 235687258 ns 234001500 ns 3 17.0939MB/s
from_wire_text/8 11461 ns 11403 ns 56089 685.104kB/s
from_wire_text/64 16117 ns 15992 ns 44872 3.81654MB/s
from_wire_text/512 51763 ns 53040 ns 10000 9.20585MB/s
from_wire_text/4k 333699 ns 336473 ns 2040 11.6094MB/s
from_wire_text/32k 2607880 ns 2600017 ns 264 12.0192MB/s
from_wire_text/256k 20869215 ns 20948706 ns 35 11.9339MB/s
from_wire_text/2M 167760690 ns 167701075 ns 4 11.926MB/s
from_wire_text/4M 334471631 ns 335402150 ns 2 11.926MB/s
to_wire_binary/8 5625 ns 5616 ns 100000 1.3585MB/s
to_wire_binary/64 5634 ns 5616 ns 100000 10.868MB/s
to_wire_binary/512 5747 ns 5702 ns 112179 85.6388MB/s
to_wire_binary/4k 6130 ns 6119 ns 112179 638.398MB/s
to_wire_binary/32k 12251 ns 12273 ns 57200 2.4866GB/s
to_wire_binary/256k 251085 ns 250358 ns 2804 998.569MB/s
to_wire_binary/2M 2504876 ns 2507159 ns 280 797.716MB/s
to_wire_binary/4M 6222666 ns 6267897 ns 112 638.173MB/s
from_wire_binary/8 5194 ns 5304 ns 100000 1.43841MB/s
from_wire_binary/64 5277 ns 5284 ns 112179 11.55MB/s
from_wire_binary/512 5235 ns 5145 ns 112179 94.897MB/s
from_wire_binary/4k 5354 ns 5424 ns 112179 720.244MB/s
from_wire_binary/32k 7479 ns 7475 ns 89743 4.08277GB/s
from_wire_binary/256k 24681 ns 24475 ns 28045 9.97506GB/s
from_wire_binary/2M 631601 ns 626091 ns 897 3.11955GB/s
from_wire_binary/4M 1309594 ns 1313034 ns 499 2.97498GB/s

-----Original Message-----
From: Boost-users [mailto:boost-users-bounces_at_[hidden]] On Behalf Of Georg Gast
Sent: Sunday, September 25, 2016 11:38 AM
To: boost-users_at_[hidden]
Subject: Re: [Boost-users] [serialization] Runtime overhead of serialization archives

Am 25.09.2016 um 07:05 schrieb Ernest Zaslavsky:
> I guess you are still comparing release to debug version. I've ran
> your code and this is what I've got
>
> Win7 x64, VS2015 Update3, Release, x64
>
> Run on (8 X 3392 MHz CPU s)
> 09/25/16 07:36:53
> Benchmark Time CPU Iterations
> ------------------------------------------------------------
> to_wire_xml/8 39564 ns 39980 ns 17949 195.409kB/s
> to_wire_xml/64 98915 ns 98035 ns 7479 637.527kB/s
> to_wire_xml/512 583376 ns 583961 ns 1122 856.222kB/s
> to_wire_xml/4k 4494721 ns 4428415 ns 155 903.258kB/s
> to_wire_xml/32k 35621888 ns 35100225 ns 20 911.675kB/s
> to_wire_xml/256k 285296564 ns 280801800 ns 2 911.675kB/s
> to_wire_xml/2M 2294702350 ns 2293214700 ns 1 893.069kB/s
> to_wire_xml/4M 4596100456 ns 4586429400 ns 1 893.069kB/s
> from_wire_xml/8 44701 ns 44361 ns 15473 176.11kB/s
> from_wire_xml/64 97779 ns 98035 ns 7479 637.527kB/s
> from_wire_xml/512 523956 ns 530403 ns 1000 942.679kB/s
> from_wire_xml/4k 3919513 ns 3877482 ns 173 1031.6kB/s
> from_wire_xml/32k 30990532 ns 31200200 ns 22 1025.63kB/s
> from_wire_xml/256k 248254367 ns 249601600 ns 3 1025.63kB/s
> from_wire_xml/2M 1990579271 ns 1981212700 ns 1 1033.71kB/s
> from_wire_xml/8M 7927240207 ns 7924850800 ns 1 1033.71kB/s
> to_wire_text/8 13381 ns 13142 ns 49857 594.483kB/s
> to_wire_text/64 31969 ns 31985 ns 22436 1.90827MB/s
> to_wire_text/512 180335 ns 179751 ns 4079 2.71643MB/s
> to_wire_text/4k 1363654 ns 1375560 ns 499 2.83975MB/s
> to_wire_text/32k 10990438 ns 10968820 ns 64 2.84898MB/s
> to_wire_text/256k 86883137 ns 88400567 ns 9 2.82804MB/s
> to_wire_text/2M 696132001 ns 686404400 ns 1 2.91373MB/s
> to_wire_text/4M 1398212634 ns 1388408900 ns 1 2.881MB/s
> from_wire_text/8 11158 ns 11195 ns 64102 697.873kB/s
> from_wire_text/64 25274 ns 25588 ns 28045 2.38534MB/s
> from_wire_text/512 138245 ns 137666 ns 4986 3.54685MB/s
> from_wire_text/4k 1047166 ns 1046497 ns 641 3.73269MB/s
> from_wire_text/32k 8304279 ns 8320053 ns 90 3.75599MB/s
> from_wire_text/256k 66510527 ns 66654973 ns 11 3.75066MB/s
> from_wire_text/2M 533393808 ns 530403400 ns 1 3.77071MB/s
> from_wire_text/4M 1055956857 ns 1060806800 ns 1 3.77071MB/s
> to_wire_binary/8 5444 ns 5460 ns 100000 1.39732MB/s
> to_wire_binary/64 5411 ns 5424 ns 112179 11.2538MB/s
> to_wire_binary/512 5523 ns 5563 ns 112179 87.7797MB/s
> to_wire_binary/4k 5966 ns 5980 ns 112179 653.244MB/s
> to_wire_binary/32k 28940 ns 29412 ns 24929 1062.5MB/s
> to_wire_binary/256k 251626 ns 250358 ns 2804 998.569MB/s
> to_wire_binary/2M 2548630 ns 2540925 ns 264 787.115MB/s
> to_wire_binary/4M 6361041 ns 6407184 ns 112 624.299MB/s
> from_wire_binary/8 5363 ns 5284 ns 112179 1.44375MB/s
> from_wire_binary/64 5371 ns 5460 ns 100000 11.1785MB/s
> from_wire_binary/512 5386 ns 5460 ns 100000 89.4282MB/s
> from_wire_binary/4k 5483 ns 5424 ns 112179 720.244MB/s
> from_wire_binary/32k 7685 ns 7649 ns 89743 3.98998GB/s
> from_wire_binary/256k 25332 ns 25588 ns 28045 9.54136GB/s
> from_wire_binary/2M 620654 ns 625672 ns 1122 3.12164GB/s
> from_wire_binary/4M 1306333 ns 1306960 ns 561 2.98881GB/s
>
Dear Earnest,
Thanks for running my code :)

have you run my code from the post at 23.9.16 19:41 (make_array)?

In your result the XML settles at about 2.9 MB/sec (from wire) and the text archive at about 3.8 MB/sec (from wire).

My guess from this values is, that you testes the version with make_array in the serialization functions. I realized this DEBUG thing too and i fixed it in the meantime. On my desktop workstation

The make_binary_object improved the performance a lot.

Here is the current version of the source from my homepage

   Georg

<code>
// STL Archive + Stuff
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/unique_ptr.hpp>

// include headers that implement a archives in xml/text/binary format #include <boost/archive/archive_exception.hpp>

#include <boost/archive/xml_iarchive.hpp> #include <boost/archive/xml_oarchive.hpp>

#include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp>

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>

// IO stream for the to/from wire functions #include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp>

#include <memory>
#include <cstdint>
#include <vector>

#include <benchmark/benchmark.h>

// the step interval for the benchmarks
static const int range_mult = 4;
static const int range_max_step = 20;

// the test structure
struct ev_test
{
        ev_test(size_t s = 0)
        {
                m_data.resize(s);
                for (auto &c : m_data)
                        c = 1;
        }

        std::vector<uint8_t> m_data;
};

//-----------------------------------------------------------------------------
// Type carrier and its support
//----------------------------------------------------------------------------
namespace net
{
        using packet = std::vector<char>; // a packet on the wire

        class carrier_visitor_base;

        class carrier_base // the base in the queue
        {
        public:
                using ptr = std::unique_ptr<carrier_base>;

                virtual ~carrier_base() {}

                virtual void accept(carrier_visitor_base *p_visitor) = 0;
        };

        template <typename T>
        class carrier;

        class carrier_visitor_base
        {
        public:
                virtual ~carrier_visitor_base() {}

                virtual void handle(carrier<ev_test> *p_evt) = 0;
                virtual void handle(carrier<char> *p_evt) = 0;
                virtual void handle(carrier<int> *p_evt) = 0;
        };

        template <typename T>
        class carrier : public carrier_base // the specific carrier
        {
        public:
                explicit carrier() : m_data() {}

                explicit carrier(const T &data) : m_data(data) {}
                virtual void accept(carrier_visitor_base *p_visitor) override
                {
                        p_visitor->handle(this);
                }

                T &data() { return m_data; }
        private:
                T m_data;
        };
} // ns net

//----------------------------------------------------------------------------
// external serialization function
//----------------------------------------------------------------------------
BOOST_SERIALIZATION_SPLIT_FREE(ev_test)
namespace boost
{
        namespace serialization
        {
                // serialization function for carrier_base
                template <class Archive>
                void serialize(Archive &ar, net::carrier_base &t, const unsigned int
                        version)
                {
                }

                // serialization function for net::carrier<T>
                template <class Archive, typename T>
                void serialize(Archive &ar, net::carrier<T> &t, const unsigned int
version)
                {
                        ar &boost::serialization::make_nvp(
                                "carrier_base",
                                boost::serialization::base_object<net::carrier_base>(t));

                        auto &data = t.data();
                        ar &BOOST_SERIALIZATION_NVP(data);
                }

                // serialization function for ev_test
                template <class Archive>
                inline void save(Archive &ar, const ev_test &t, const unsigned int
version)
                {
                        size_t size = t.m_data.size();
                        ar &BOOST_SERIALIZATION_NVP(size);
                        ar &boost::serialization::make_nvp(
                                "m_data",
                        
boost::serialization::make_binary_object(const_cast<uint8_t*>(t.m_data.data()),
t.m_data.size()));
                }
                template <class Archive>
                inline void load(Archive &ar, ev_test &t, const unsigned int version)
                {
                        size_t size = 0;
                        ar &BOOST_SERIALIZATION_NVP(size);
                        t.m_data.resize(size);

                        ar &boost::serialization::make_nvp(
                                "m_data",
                                boost::serialization::make_binary_object(t.m_data.data(),
t.m_data.size()));
                }
        }
}

// we must export all carrier
BOOST_SERIALIZATION_SHARED_PTR(net::carrier<ev_test>)
BOOST_CLASS_EXPORT(net::carrier<ev_test>)

//----------------------------------------------------------------------------
// the traits for the boost serialization tests
//----------------------------------------------------------------------------
struct boost_xml_trait
{
        static const char *name() { return "boost_xml_test: ev_test: "; }

        typedef boost::archive::xml_oarchive oarchive;
        typedef boost::archive::xml_iarchive iarchive; };

struct boost_text_trait
{
        static const char *name() { return "boost_text_test: ev_test: "; }

        typedef boost::archive::text_oarchive oarchive;
        typedef boost::archive::text_iarchive iarchive; };

struct boost_binary_trait
{
        static const char *name() { return "boost_binary_test: ev_test: "; }

        typedef boost::archive::binary_oarchive oarchive;
        typedef boost::archive::binary_iarchive iarchive; };

template <typename archive_trait>
struct boost_test
{
        static const char *name() { return archive_trait::name(); }
        static size_t msg_size() { return 600; }

        // throws boost::archive::archive_exception
        template <typename T>
        static net::packet to_wire(const T &data)
        {
                using namespace boost::iostreams;

                using T1 = typename std::remove_cv<T>::type;
                using BT = typename std::remove_reference<T1>::type;
                net::carrier_base::ptr p_carrier =
                        std::make_unique<net::carrier<BT>>(data);

                net::packet p;
                p.reserve(msg_size());
                {
                        back_insert_device<net::packet> sink(p);
                        stream<back_insert_device<net::packet>> os{ sink };

                        typename archive_trait::oarchive oa(os);
                        oa << BOOST_SERIALIZATION_NVP(p_carrier);
                }
                return p;
        }

        // throws boost::archive::archive_exception
        static net::carrier_base::ptr from_wire(const net::packet &data)
        {
                using namespace boost::iostreams;
                array_source source{ data.data(), data.size() };
                stream<array_source> is{ source };

                net::carrier_base::ptr p_carrier;
                typename archive_trait::iarchive ia(is); // this takes the most time
                ia >> BOOST_SERIALIZATION_NVP(p_carrier);

                return p_carrier;
        }
};

//----------------------------------------------------------------------------
// XML
//----------------------------------------------------------------------------
static void to_wire_xml(benchmark::State &state) {
        std::locale::global(std::locale("C"));
        ev_test data(state.range_x());

        while (state.KeepRunning())
        {
                boost_test<boost_xml_trait>::to_wire(data);
        }

        state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                state.range_x());
}
BENCHMARK(to_wire_xml)->Range(8, range_mult << range_max_step);

static void from_wire_xml(benchmark::State &state) {
        std::locale::global(std::locale("C"));
        auto buffer =
                boost_test<boost_xml_trait>::to_wire(ev_test(state.range_x()));

        while (state.KeepRunning())
        {
                boost_test<boost_xml_trait>::from_wire(buffer);
        }

        state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                state.range_x());
}
BENCHMARK(from_wire_xml)->Range(8, range_mult << range_max_step);

//----------------------------------------------------------------------------
// Text
//----------------------------------------------------------------------------
static void to_wire_text(benchmark::State &state) {
        std::locale::global(std::locale("C"));
        ev_test data(state.range_x());

        while (state.KeepRunning())
        {
                boost_test<boost_text_trait>::to_wire(data);
        }

        state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                state.range_x());
}
BENCHMARK(to_wire_text)->Range(8, range_mult << range_max_step);

static void from_wire_text(benchmark::State &state) {
        std::locale::global(std::locale("C"));
        auto buffer =
                boost_test<boost_text_trait>::to_wire(ev_test(state.range_x()));

        while (state.KeepRunning())
        {
                boost_test<boost_text_trait>::from_wire(buffer);
        }

        state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                state.range_x());
}
BENCHMARK(from_wire_text)->Range(8, range_mult << range_max_step);

//----------------------------------------------------------------------------
// Binary
//----------------------------------------------------------------------------
static void to_wire_binary(benchmark::State &state) {
        std::locale::global(std::locale("C"));
        ev_test data(state.range_x());

        while (state.KeepRunning())
        {
                boost_test<boost_binary_trait>::to_wire(data);
        }

        state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                state.range_x());
}
BENCHMARK(to_wire_binary)->Range(8, range_mult << range_max_step);

static void from_wire_binary(benchmark::State &state) {
        std::locale::global(std::locale("C"));

        auto buffer =
                boost_test<boost_binary_trait>::to_wire(ev_test(state.range_x()));

        while (state.KeepRunning())
        {
                boost_test<boost_binary_trait>::from_wire(buffer);
        }

        state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                state.range_x());
}
BENCHMARK(from_wire_binary)->Range(8, range_mult << range_max_step);

BENCHMARK_MAIN();
</code>

_______________________________________________
Boost-users mailing list
Boost-users_at_[hidden]
http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net