[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Make STL containers allocate aligned memory

zr

11/26/2008 4:42:00 PM

Hi,

I need to use STL containers that allocate aligned memory. My compiler
provides an aligned_malloc routine.
How can this be accomplished?

9 Answers

red floyd

11/26/2008 4:54:00 PM

0

On Nov 26, 8:42 am, zr <zvir...@gmail.com> wrote:
> Hi,
>
> I need to use STL containers that allocate aligned memory. My compiler
> provides an aligned_malloc routine.
> How can this be accomplished?

I believe you need to write a custom allocator.

zr

11/26/2008 5:02:00 PM

0

On Nov 26, 6:53 pm, red floyd <redfl...@gmail.com> wrote:
> On Nov 26, 8:42 am, zr <zvir...@gmail.com> wrote:
>
> > Hi,
>
> > I need to use STL containers that allocate aligned memory. My compiler
> > provides an aligned_malloc routine.
> > How can this be accomplished?
>
> I believe you need to write a custom allocator.

Could you please show an example of implementing such an allocator and
its usage for instantiating a vector object?

Maxim Yegorushkin

11/26/2008 5:03:00 PM

0

On Nov 26, 4:42 pm, zr <zvir...@gmail.com> wrote:

> I need to use STL containers that allocate aligned memory.

Why?

> My compiler provides an aligned_malloc routine.

It is probably provided by a library shipped with the compiler, not by
compiler itself.

> How can this be accomplished?

Something like this:

#include <memory>
#include <stdexcept>

template<class T, size_t alignment>
struct aligned_allocator : std::allocator<T>
{
template<class U>
struct rebind { typedef aligned_allocator<U, alignment> other; };

typedef std::allocator<T> base;

typedef typename base::pointer pointer;
typedef typename base::size_type size_type;

pointer allocate(size_type n)
{
if(pointer p = (pointer)aligned_malloc(n, alignment))
return p;
throw std::bad_alloc("aligned_allocator");
}

pointer allocate(size_type n, void const*)
{
return this->allocate(n);
}

void deallocate(pointer p, size_type)
{
aligned_free(p);
}
};

--
Max

Maxim Yegorushkin

11/26/2008 5:33:00 PM

0

On Nov 26, 5:03 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
> On Nov 26, 4:42 pm, zr <zvir...@gmail.com> wrote:
>
> > I need to use STL containers that allocate aligned memory.
>
> Why?
>
> > My compiler provides an aligned_malloc routine.
>
> It is probably provided by a library shipped with the compiler, not by
> compiler itself.
>
> > How can this be accomplished?
>
> Something like this:
>
> #include <memory>
> #include <stdexcept>
>
> template<class T, size_t alignment>
> struct aligned_allocator : std::allocator<T>
> {
>     template<class U>
>     struct rebind { typedef aligned_allocator<U, alignment> other; };
>
>     typedef std::allocator<T> base;
>
>     typedef typename base::pointer pointer;
>     typedef typename base::size_type size_type;
>
>     pointer allocate(size_type n)
>     {
>         if(pointer p = (pointer)aligned_malloc(n, alignment))
>             return p;
>         throw std::bad_alloc("aligned_allocator");
>     }
>
>     pointer allocate(size_type n, void const*)
>     {
>         return this->allocate(n);
>     }
>
>     void deallocate(pointer p, size_type)
>     {
>         aligned_free(p);
>     }
>
> };

Usage is:

typedef std::vector<X, aligned_allocator<X, required_alignment> >
VecX;

--
Max

Hendrik Schober

11/26/2008 5:58:00 PM

0

zr wrote:
> On Nov 26, 6:53 pm, red floyd <redfl...@gmail.com> wrote:
>> On Nov 26, 8:42 am, zr <zvir...@gmail.com> wrote:
>>
>>> Hi,
>>> I need to use STL containers that allocate aligned memory. My compiler
>>> provides an aligned_malloc routine.
>>> How can this be accomplished?
>> I believe you need to write a custom allocator.
>
> Could you please show an example of implementing such an allocator and
> its usage for instantiating a vector object?

http://www.ddj.com/cpp...

HTH,

Schobi

zr

11/26/2008 6:07:00 PM

0

On Nov 26, 7:32 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
> On Nov 26, 5:03 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
> wrote:
>
>
>
> > On Nov 26, 4:42 pm, zr <zvir...@gmail.com> wrote:
>
> > > I need to use STL containers that allocate aligned memory.
>
> > Why?
>
> > > My compiler provides an aligned_malloc routine.
>
> > It is probably provided by a library shipped with the compiler, not by
> > compiler itself.
>
> > > How can this be accomplished?
>
> > Something like this:
>
> > #include <memory>
> > #include <stdexcept>
>
> > template<class T, size_t alignment>
> > struct aligned_allocator : std::allocator<T>
> > {
> >     template<class U>
> >     struct rebind { typedef aligned_allocator<U, alignment> other; };
>
> >     typedef std::allocator<T> base;
>
> >     typedef typename base::pointer pointer;
> >     typedef typename base::size_type size_type;
>
> >     pointer allocate(size_type n)
> >     {
> >         if(pointer p = (pointer)aligned_malloc(n, alignment))
> >             return p;
> >         throw std::bad_alloc("aligned_allocator");
> >     }
>
> >     pointer allocate(size_type n, void const*)
> >     {
> >         return this->allocate(n);
> >     }
>
> >     void deallocate(pointer p, size_type)
> >     {
> >         aligned_free(p);
> >     }
>
> > };
>
> Usage is:
>
>     typedef std::vector<X, aligned_allocator<X, required_alignment> >
> VecX;
>
> --
> Max

Max, thanks. I wrote a quick test on your proposal. Unfortunately, got
a compilation error:
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility
(419) : error C2664: 'aligned_allocator<T,alignment>::aligned_allocator
(const aligned_allocator<T,alignment> &) throw()' : cannot convert
parameter 1 from 'aligned_allocator<T,alignment>' to 'const
aligned_allocator<T,alignment> &'
with
[
T=std::_Aux_cont,
alignment=64
]
and
[
T=int,
alignment=64
]
and
[
T=std::_Aux_cont,
alignment=64
]
Reason: cannot convert from 'aligned_allocator<T,alignment>'
to 'const aligned_allocator<T,alignment>'
with
[
T=int,
alignment=64
]
and
[
T=std::_Aux_cont,
alignment=64
]
No user-defined-conversion operator available that can perform
this conversion, or the operator cannot be called
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
\xutility(417) : while compiling class template member function
'std::_Container_base_aux_alloc_real<_Alloc>::_Container_base_aux_alloc_real
(_Alloc)'
with
[
_Alloc=aligned_allocator<int,64>
]
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
\vector(421) : see reference to class template instantiation
'std::_Container_base_aux_alloc_real<_Alloc>' being compiled
with
[
_Alloc=aligned_allocator<int,64>
]
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
\vector(439) : see reference to class template instantiation
'std::_Vector_val<_Ty,_Alloc>' being compiled
with
[
_Ty=int,
_Alloc=aligned_allocator<int,64>
]
.\main.cpp(38) : see reference to class template instantiation
'std::vector<_Ty,_Ax>' being compiled
with
[
_Ty=int,
_Ax=aligned_allocator<int,64>
]

Following is the source of the test:


#include <malloc.h>
#include <memory>
#include <stdexcept>
#include <vector>

template<class T, size_t alignment>
struct aligned_allocator : std::allocator<T>
{
template<class U>
struct rebind { typedef aligned_allocator<U, alignment> other; };

typedef std::allocator<T> base;

typedef typename base::pointer pointer;
typedef typename base::size_type size_type;

pointer allocate(size_type n)
{
if(pointer p = (pointer)_aligned_malloc(n, alignment))
return p;
throw std::bad_alloc("aligned_allocator");
}

pointer allocate(size_type n, void const*)
{
return this->allocate(n);
}

void deallocate(pointer p, size_type)
{
_aligned_free(p);
}

};

int main(int argc, char* argv[])
{
std::vector<int, aligned_allocator<int, 64> > v(1024);
}

zr

11/26/2008 6:34:00 PM

0

On Nov 26, 7:03 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
> On Nov 26, 4:42 pm, zr <zvir...@gmail.com> wrote:
>
> > I need to use STL containers that allocate aligned memory.
>
> Why?

I'm using IA SIMD instructions that perform best on memory aligned to
16 bytes.

Ron AF Greve

11/26/2008 6:52:00 PM

0

Hi,

Here an example from Bill himself (custom allocator, I figure to align the
memory itself is easy enough).

http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallo...




Regards, Ron AF Greve

http://www.InformationSuper...

"zr" <zvirack@gmail.com> wrote in message
news:bc292154-3220-460f-8ef3-38627fe1bc06@w35g2000yqm.googlegroups.com...
> Hi,
>
> I need to use STL containers that allocate aligned memory. My compiler
> provides an aligned_malloc routine.
> How can this be accomplished?
>


Maxim Yegorushkin

11/27/2008 11:52:00 AM

0

On Nov 26, 6:06 pm, zr <zvir...@gmail.com> wrote:
> On Nov 26, 7:32 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
> wrote:
>
>
>
> > On Nov 26, 5:03 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
> > wrote:
>
> > > On Nov 26, 4:42 pm, zr <zvir...@gmail.com> wrote:
>
> > > > I need to use STL containers that allocate aligned memory.
>
> > > Why?
>
> > > > My compiler provides an aligned_malloc routine.
>
> > > It is probably provided by a library shipped with the compiler, not by
> > > compiler itself.
>
> > > > How can this be accomplished?
>
> > > Something like this:
>
> > > #include <memory>
> > > #include <stdexcept>
>
> > > template<class T, size_t alignment>
> > > struct aligned_allocator : std::allocator<T>
> > > {
> > >     template<class U>
> > >     struct rebind { typedef aligned_allocator<U, alignment> other; };
>
> > >     typedef std::allocator<T> base;
>
> > >     typedef typename base::pointer pointer;
> > >     typedef typename base::size_type size_type;
>
> > >     pointer allocate(size_type n)
> > >     {
> > >         if(pointer p = (pointer)aligned_malloc(n, alignment))
> > >             return p;
> > >         throw std::bad_alloc("aligned_allocator");
> > >     }
>
> > >     pointer allocate(size_type n, void const*)
> > >     {
> > >         return this->allocate(n);
> > >     }
>
> > >     void deallocate(pointer p, size_type)
> > >     {
> > >         aligned_free(p);
> > >     }
>
> > > };
>
> > Usage is:
>
> >     typedef std::vector<X, aligned_allocator<X, required_alignment> >
> > VecX;
>
> > --
> > Max
>
> Max, thanks. I wrote a quick test on your proposal. Unfortunately, got
> a compilation error:
> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xutility
> (419) : error C2664: 'aligned_allocator<T,alignment>::aligned_allocator
> (const aligned_allocator<T,alignment> &) throw()' : cannot convert
> parameter 1 from 'aligned_allocator<T,alignment>' to 'const
> aligned_allocator<T,alignment> &'
>         with
>         [
>             T=std::_Aux_cont,
>             alignment=64
>         ]
>         and
>         [
>             T=int,
>             alignment=64
>         ]
>         and
>         [
>             T=std::_Aux_cont,
>             alignment=64
>         ]
>         Reason: cannot convert from 'aligned_allocator<T,alignment>'
> to 'const aligned_allocator<T,alignment>'
>         with
>         [
>             T=int,
>             alignment=64
>         ]
>         and
>         [
>             T=std::_Aux_cont,
>             alignment=64
>         ]
>         No user-defined-conversion operator available that can perform
> this conversion, or the operator cannot be called
>         C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
> \xutility(417) : while compiling class template member function
> 'std::_Container_base_aux_alloc_real<_Alloc>::_Container_base_aux_alloc_real
> (_Alloc)'
>         with
>         [
>             _Alloc=aligned_allocator<int,64>
>         ]
>         C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
> \vector(421) : see reference to class template instantiation
> 'std::_Container_base_aux_alloc_real<_Alloc>' being compiled
>         with
>         [
>             _Alloc=aligned_allocator<int,64>
>         ]
>         C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
> \vector(439) : see reference to class template instantiation
> 'std::_Vector_val<_Ty,_Alloc>' being compiled
>         with
>         [
>             _Ty=int,
>             _Alloc=aligned_allocator<int,64>
>         ]
>         .\main.cpp(38) : see reference to class template instantiation
> 'std::vector<_Ty,_Ax>' being compiled
>         with
>         [
>             _Ty=int,
>             _Ax=aligned_allocator<int,64>
>         ]
>
> Following is the source of the test:
>
> #include <malloc.h>
> #include <memory>
> #include <stdexcept>
> #include <vector>
>
> template<class T, size_t alignment>
> struct aligned_allocator : std::allocator<T>
> {
>     template<class U>
>     struct rebind { typedef aligned_allocator<U, alignment> other; };
>
>     typedef std::allocator<T> base;
>
>     typedef typename base::pointer pointer;
>     typedef typename base::size_type size_type;
>
>     pointer allocate(size_type n)
>     {
>         if(pointer p = (pointer)_aligned_malloc(n, alignment))
>             return p;
>         throw std::bad_alloc("aligned_allocator");
>     }
>
>     pointer allocate(size_type n, void const*)
>     {
>         return this->allocate(n);
>     }
>
>     void deallocate(pointer p, size_type)
>     {
>         _aligned_free(p);
>     }
>
> };
>
> int main(int argc, char* argv[])
> {
>         std::vector<int, aligned_allocator<int, 64> > v(1024);
> }

Strange, it compiles fine with M$VC 2005. It looks like
aligned_allocator needs a conversion constructor. Try adding these
constructors:

aligned_allocator()
{}

template<class U>
aligned_allocator(U const&)
{}

--
Max