void test_parcel_serialization(hpx::parcelset::parcel outp,
    int out_archive_flags, bool zero_copy)
{
    // serialize data
    std::vector<hpx::serialization::serialization_chunk> out_chunks;
    std::size_t arg_size = get_archive_size(outp, out_archive_flags,
        zero_copy ? &out_chunks : nullptr);
    std::vector<char> out_buffer;

    out_buffer.resize(arg_size + HPX_PARCEL_SERIALIZATION_OVERHEAD);

    {
        // create an output archive and serialize the parcel
        hpx::serialization::output_archive archive(
            out_buffer, out_archive_flags,
            zero_copy ? &out_chunks : nullptr);
        archive << outp;

        arg_size = archive.bytes_written();
    }

    out_buffer.resize(arg_size);

    // deserialize data
    hpx::parcelset::parcel inp;

    {
        // create an input archive and deserialize the parcel
        hpx::serialization::input_archive archive(
            out_buffer, arg_size, &out_chunks);

        archive >> inp;
    }

    // make sure the parcel has been de-serialized properly
    HPX_TEST_EQ(outp.source_id(), inp.source_id());
    HPX_TEST_EQ(outp.destination_locality(), inp.destination_locality());
    HPX_TEST_EQ(outp.start_time(), inp.start_time());

    hpx::actions::base_action *outact = outp.get_action();
    hpx::actions::base_action *inact = inp.get_action();

    HPX_TEST_EQ(outact->get_component_type(), inact->get_component_type());
    HPX_TEST_EQ(outact->get_action_name(), inact->get_action_name());
    HPX_TEST_EQ(int(outact->get_action_type()), int(inact->get_action_type()));
    HPX_TEST_EQ(outact->get_parent_locality_id(), inact->get_parent_locality_id());
    HPX_TEST_EQ(outact->get_parent_thread_id(), inact->get_parent_thread_id());
    HPX_TEST_EQ(outact->get_parent_thread_phase(), inact->get_parent_thread_phase());
    HPX_TEST_EQ(int(outact->get_thread_priority()), int(inact->get_thread_priority()));
    HPX_TEST_EQ(int(outact->get_thread_stacksize()), int(inact->get_thread_stacksize()));
    HPX_TEST_EQ(outact->get_parent_thread_phase(), inact->get_parent_thread_phase());

    std::unique_ptr<hpx::actions::continuation> outcont = outp.get_continuation();
    std::unique_ptr<hpx::actions::continuation> incont = inp.get_continuation();

    HPX_TEST_EQ(outcont->get_continuation_name(), incont->get_continuation_name());
    HPX_TEST_EQ(outcont->get_id(), incont->get_id());

    //// invoke action encapsulated in inp
    //naming::address const* inaddrs = pin.get_destination_addrs();
    //hpx::threads::thread_init_data data;
    //inact->get_thread_init_data(inaddrs[0].address_, data);
    //data.func(hpx::threads::wait_signaled);
}
示例#2
0
double benchmark_serialization(std::size_t data_size, std::size_t iterations,
    bool continuation, bool zerocopy)
{
    hpx::naming::id_type const here = hpx::find_here();
    hpx::naming::address addr(hpx::get_locality(),
        hpx::components::component_invalid,
        reinterpret_cast<boost::uint64_t>(&test_function));

    // compose archive flags
#ifdef BOOST_BIG_ENDIAN
    std::string endian_out =
        hpx::get_config_entry("hpx.parcel.endian_out", "big");
#else
    std::string endian_out =
        hpx::get_config_entry("hpx.parcel.endian_out", "little");
#endif

    unsigned int out_archive_flags = 0U;
    if (endian_out == "little")
        out_archive_flags |= hpx::serialization::endian_little;
    else if (endian_out == "big")
        out_archive_flags |= hpx::serialization::endian_big;
    else {
        HPX_ASSERT(endian_out =="little" || endian_out == "big");
    }

    std::string array_optimization =
        hpx::get_config_entry("hpx.parcel.array_optimization", "1");

    if (boost::lexical_cast<int>(array_optimization) == 0)
    {
        out_archive_flags |= hpx::serialization::disable_array_optimization;
        out_archive_flags |= hpx::serialization::disable_data_chunking;
    }
    else
    {
        std::string zero_copy_optimization =
            hpx::get_config_entry("hpx.parcel.zero_copy_optimization", "1");
        if (boost::lexical_cast<int>(zero_copy_optimization) == 0)
        {
            out_archive_flags |= hpx::serialization::disable_data_chunking;
        }
    }

    // create argument for action
    std::vector<double> data;
    data.resize(data_size);

    hpx::serialization::serialize_buffer<double> buffer(data.data(), data.size(),
        hpx::serialization::serialize_buffer<double>::reference);

    // create a parcel with/without continuation
    hpx::parcelset::parcel outp;
    if (continuation) {
        outp = hpx::parcelset::parcel(here, addr,
            new hpx::actions::transfer_action<test_action>(
                hpx::threads::thread_priority_normal, buffer),
            new hpx::actions::typed_continuation<int>(here));
    }
    else {
        outp = hpx::parcelset::parcel(here, addr,
            new hpx::actions::transfer_action<test_action>(
                hpx::threads::thread_priority_normal, buffer));
    }

    outp.set_parcel_id(hpx::parcelset::parcel::generate_unique_id());
    outp.set_source(here);

    std::vector<hpx::serialization::serialization_chunk>* chunks = 0;
    if (zerocopy)
        chunks = new std::vector<hpx::serialization::serialization_chunk>();

    boost::uint32_t dest_locality_id = outp.get_destination_locality_id();
    hpx::util::high_resolution_timer t;

    for (std::size_t i = 0; i != iterations; ++i)
    {
        std::size_t arg_size = get_archive_size(outp, out_archive_flags, chunks);
        std::vector<char> out_buffer;

        out_buffer.resize(arg_size + HPX_PARCEL_SERIALIZATION_OVERHEAD);

        {
            // create an output archive and serialize the parcel
            hpx::serialization::output_archive archive(
                out_buffer, out_archive_flags, dest_locality_id, chunks);
            archive << outp;
            arg_size = archive.bytes_written();
        }

        hpx::parcelset::parcel inp;

        {
            // create an input archive and deserialize the parcel
            hpx::serialization::input_archive archive(
                out_buffer, arg_size, chunks);

            archive >> inp;
        }

        if (chunks)
            chunks->clear();
    }

    return t.elapsed();
}