Beispiel #1
0
  //////////////////////////////////////////////////////////////////////////////
  // Deallocate a raw buffer of bytes using an allocator
  //////////////////////////////////////////////////////////////////////////////
  template<class Allocator> inline void
  deallocate( Allocator& a, byte* ptr, std::size_t nbytes = 0)
  {
    // Allocator element types
    typedef typename Allocator::value_type value_type;

    // Compute alignment values for fixing address
    BOOST_STATIC_CONSTANT(std::size_t, size  = sizeof(value_type)       );
    BOOST_STATIC_CONSTANT(std::size_t, align = NT2_CONFIG_ALIGNMENT     );
    BOOST_STATIC_CONSTANT(std::size_t, fix   = ~(std::size_t(align-1))  );

    // How many elements are needed ot store proper number of bytes
    std::size_t nelems = align_on<size>(nbytes+align+sizeof(void*))/size;

    void* base = reinterpret_cast<void**>(ptr)[- 1];
    a.deallocate(reinterpret_cast<typename Allocator::pointer>(base),nelems);
  }
Beispiel #2
0
  byte* allocate( std::size_t nbytes )
  {
    void *result;
    BOOST_STATIC_CONSTANT(std::size_t, align = NT2_CONFIG_ALIGNMENT );

    #if defined(NT2_CONFIG_SUPPORT_POSIX_MEMALIGN)
    //////////////////////////////////////////////////////////////////////////////
    // POSIX systems use posix_memalign
    //////////////////////////////////////////////////////////////////////////////
    if(posix_memalign(&result, align, nbytes))
    {
      NT2_THROW( std::bad_alloc() );
      result = 0;
    }
    #elif defined (_MSC_VER)
    //////////////////////////////////////////////////////////////////////////////
    // MSVC systems use _aligned_malloc
    //////////////////////////////////////////////////////////////////////////////
    if( !(result = _aligned_malloc(nbytes, align) ) )
    {
      NT2_THROW( std::bad_alloc() );
      result = 0;
    }
    #else
    //////////////////////////////////////////////////////////////////////////////
    // Other systems do the funky pointer stashing
    //////////////////////////////////////////////////////////////////////////////
    void *base;
    BOOST_STATIC_CONSTANT(std::size_t, fix = ~(std::size_t(align-1)));
    if( !(base = ::malloc(nbytes+align+sizeof(void*))) )
    {
      NT2_THROW( std::bad_alloc() );
      result = 0;
    }
    else
    {
      std::size_t  ref      = reinterpret_cast<std::size_t>(base)+sizeof(void*);
      std::size_t  stashed  = (ref & fix) + align;
      result = reinterpret_cast<void*>(stashed);
      reinterpret_cast<void**>(result)[-1] = base;
    }
    #endif

    return reinterpret_cast<byte*>(result);
  }
Beispiel #3
0
    ////////////////////////////////////////////////////////////////////////////
    // Forward, non-periodic case
    ////////////////////////////////////////////////////////////////////////////
    inline result_type eval ( A0 const& a0, A1 const& a1
                            , boost::mpl::false_ const&, boost::mpl::true_ const&
                            ) const
    {
      BOOST_STATIC_CONSTANT( std::size_t, card    = boost::simd::meta::cardinal_of<result_type>::value );
      BOOST_STATIC_CONSTANT( std::size_t, offset  = std::size_t(A3::value)/card*card      );
      BOOST_STATIC_CONSTANT( std::size_t, bytes   = 16u/card                              );
      BOOST_STATIC_CONSTANT( std::size_t, shifta  = bytes*(A3::value%card)                );
      BOOST_STATIC_CONSTANT( std::size_t, shiftb  = bytes*(card-A3::value%card)           );

      typedef typename dispatch::meta::as_integer<result_type>::type itype;

      result_type a     = boost::simd::load<result_type>(a0,a1+offset);
      result_type b     = boost::simd::load<result_type>(a0,a1+offset+card);
      __m128i sa        = _mm_srli_si128(boost::simd::bitwise_cast<itype>(a.data_),shifta);
      __m128i sb        = _mm_slli_si128(boost::simd::bitwise_cast<itype>(b.data_),shiftb);
      return boost::simd::bitwise_cast<result_type>(_mm_or_si128(sa,sb));
    }
Beispiel #4
0
    ////////////////////////////////////////////////////////////////////////////
    // Periodic case - Just add up to the runtime offset
    ////////////////////////////////////////////////////////////////////////////
    template<class Fwd> inline result_type
    eval( A0 const& a0, A1 const& a1, boost::mpl::true_ const&, Fwd const&) const
    {
      BOOST_STATIC_CONSTANT
      ( std::size_t
      , offset  = std::size_t(A3::value)
      );

      return boost::simd::load<result_type>(a0,a1+offset);
    }
Beispiel #5
0
    ////////////////////////////////////////////////////////////////////////////
    // Forward, non-periodic case
    ////////////////////////////////////////////////////////////////////////////
    inline result_type eval ( A0 const& a0, A1 const& a1
                            , boost::mpl::false_ const&, boost::mpl::true_ const&
                            ) const
    {
      BOOST_STATIC_CONSTANT( std::size_t, card    = boost::simd::meta::cardinal_of<result_type>::value );
      BOOST_STATIC_CONSTANT( std::size_t, offset  = std::size_t(A3::value)/card           );
      BOOST_STATIC_CONSTANT( std::size_t, bytes   = 16u/card                              );
      BOOST_STATIC_CONSTANT( std::size_t, shifta  = bytes*(A3::value%card)                );
      BOOST_STATIC_CONSTANT( std::size_t, shiftb  = bytes*(card-A3::value%card)           );

      typedef typename boost::simd::meta::as_simd< typename meta::scalar_of<result_type>::type
                                    , boost::simd::tag::sse_
                                    >::type     raw_type;

      result_type a     = boost::simd::load<result_type>(a0,a1+offset);
      result_type b     = boost::simd::load<result_type>(a0,a1+offset+1);
      __m128i sa        = _mm_srli_si128(boost::simd::bitwise_cast<__m128i>(a.data_),shifta);
      __m128i sb        = _mm_slli_si128(boost::simd::bitwise_cast<__m128i>(b.data_),shiftb);
      result_type that  = { boost::simd::bitwise_cast<raw_type>(_mm_or_si128(sa,sb)) };
      return that;
    }
Beispiel #6
0
struct BOOST_PP_CAT(AUX778076_OP_PREFIX,_wknd)
{
    BOOST_STATIC_CONSTANT(T, value = (n1 AUX778076_OP_TOKEN n2));
    typedef integral_c<T,value> type;
};
Beispiel #7
0
void sequenced_index_sort(Node* header,Compare comp)
{
  /* Musser's mergesort, see http://www.cs.rpi.edu/~musser/gp/List/lists1.html.
   * The implementation is a little convoluted: in the original code
   * counter elements and carry are std::lists: here we do not want
   * to use multi_index instead, so we do things at a lower level, managing
   * directly the internal node representation.
   * Incidentally, the implementations I've seen of this algorithm (SGI,
   * Dinkumware, STLPort) are not exception-safe: this is. Moreover, we do not
   * use any dynamic storage.
   */

  if(header->next()==header->impl()||
     header->next()->next()==header->impl())return;

  BOOST_STATIC_CONSTANT(
    std::size_t,
    max_fill=(std::size_t)std::numeric_limits<std::size_t>::digits+1);

  aligned_storage<
    sizeof(sequenced_index_node_impl)>      carry_spc;
  sequenced_index_node_impl&                carry=
    *static_cast<sequenced_index_node_impl*>(carry_spc.address());
  aligned_storage<
    sizeof(
      sequenced_index_node_impl[max_fill])> counter_spc;
  sequenced_index_node_impl*                counter=
    static_cast<sequenced_index_node_impl*>(counter_spc.address());
  std::size_t                               fill=0;

  carry.prior()=carry.next()=&carry;
  counter[0].prior()=counter[0].next()=&counter[0];

  BOOST_TRY{
    while(header->next()!=header->impl()){
      sequenced_index_node_impl::relink(carry.next(),header->next());
      std::size_t i=0;
      while(i<fill&&counter[i].next()!=&counter[i]){
        sequenced_index_collate<Node>(&carry,&counter[i++],comp);
      }
      sequenced_index_node_impl::swap(&carry,&counter[i]);
      if(i==fill){
        ++fill;
        counter[fill].prior()=counter[fill].next()=&counter[fill];
      }
    }

    for(std::size_t i=1;i<fill;++i){
      sequenced_index_collate<Node>(&counter[i],&counter[i-1],comp);
    }
    sequenced_index_node_impl::swap(header->impl(),&counter[fill-1]);
  }
  BOOST_CATCH(...)
  {
    sequenced_index_node_impl::relink(header->impl(),carry.next(),&carry);
    for(std::size_t i=0;i<=fill;++i){
      sequenced_index_node_impl::relink(
        header->impl(),counter[i].next(),&counter[i]);
    }
    BOOST_RETHROW;
  }
Beispiel #8
0
static void do_test(bool do_count_cleanup_time = false) {
    BOOST_STATIC_CONSTANT(std::size_t, c_run_count = 5000000);
    typedef std::vector<char> str_t;
    typedef boost::variant<int, str_t, float> var_t;

    const char hello1_c[] = "hello long word";
    const str_t hello1(hello1_c, hello1_c + sizeof(hello1_c));

    const char hello2_c[] = "Helllloooooooooooooooooooooooooooooooo!!!!!!!!!!!!!";
    const str_t hello2(hello2_c, hello2_c + sizeof(hello2_c));

    if (do_count_cleanup_time) {
        std::cout << "#############################################\n";
        std::cout << "#############################################\n";
        std::cout << "NOW TIMES WITH DATA DESTRUCTION\n";
        std::cout << "#############################################\n";
    }

    std::vector<var_t> data_from, data_to;
    data_from.resize(c_run_count, hello1);
    data_to.reserve(c_run_count);
    {
        scope sc("boost::variant(const variant&) copying speed");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to.push_back(data_from[i]);

        }

        if (do_count_cleanup_time) {
            data_to.clear();
            data_from.clear();
        }
    }

    data_from.resize(c_run_count, hello1);
    data_to.clear();
    data_to.reserve(c_run_count);
    {
        scope sc("boost::variant(variant&&) moving speed");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to.push_back(boost::move(data_from[i]));
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            data_from.clear();
        }
    }

    std::cout << "#############################################\n";

    data_from.clear();
    data_from.resize(c_run_count, hello2);
    data_to.clear();
    data_to.resize(c_run_count, hello2);
    {
        scope sc("boost::variant=(const variant&) copying speed on same types");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to[i] = data_from[i];
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            data_from.clear();
        }
    }

    data_from.resize(c_run_count, hello2);
    data_to.clear();
    data_to.resize(c_run_count, hello2);
    {
        scope sc("boost::variant=(variant&&) moving speed on same types");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to[i] = boost::move(data_from[i]);
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            data_from.clear();
        }
    }

    std::cout << "#############################################\n";

    data_from.clear();
    data_from.resize(c_run_count, hello2);

    data_to.clear();
    data_to.resize(c_run_count, var_t(0));
    {
        scope sc("boost::variant=(const variant&) copying speed on different types");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to[i] = data_from[i];
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            data_from.clear();
        }
    }

    data_from.resize(c_run_count, hello2);
    data_to.clear();
    data_to.resize(c_run_count, var_t(0));
    {
        scope sc("boost::variant=(variant&&) moving speed on different types");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to[i] = boost::move(data_from[i]);
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            data_from.clear();
        }
    }

    std::cout << "#############################################\n";

    data_from.clear();
    data_from.resize(c_run_count, var_t(0));

    data_to.clear();
    data_to.resize(c_run_count, hello2);
    {
        scope sc("boost::variant=(const variant&) copying speed on different types II");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to[i] = data_from[i];
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            data_from.clear();
        }
    }

    data_from.resize(c_run_count, var_t(0));
    data_to.clear();
    data_to.resize(c_run_count, hello2);
    {
        scope sc("boost::variant=(variant&&) moving speed on different types II");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to[i] = boost::move(data_from[i]);
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            data_from.clear();
        }
    }


    std::cout << "#############################################\n";

    std::vector<str_t> s1(c_run_count, hello2);
    data_to.clear();
    data_to.resize(c_run_count, var_t(0));

    {
        scope sc("boost::variant=(const T&) copying speed");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to[i] = s1[i];
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            s1.clear();
        }
    }

    std::vector<str_t> s2(c_run_count, hello2);
    data_to.clear();
    data_to.resize(c_run_count, var_t(0));
    {
        scope sc("boost::variant=(T&&) moving speed");
        for (std::size_t i = 0; i < c_run_count; ++i) {
            data_to[i] = boost::move(s2[i]);
        }

        if (do_count_cleanup_time) {
            data_to.clear();
            s2.clear();
        }
    }
}