[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.c++

problem with alignment

abir

11/11/2008 6:47:00 AM

In my program i wan to use a certain type as both type T1 (usually
non-pod)
and also T2 (usually size_t)

so an union like this doesn't work
template<typename T>
union utype{
T v_;
std::size_t sz_;
};
utype* memory_;
where T is
struct nonpod{
int x;
int y;
nonpod(){}
};

I am not familiar to aligned_storage or its usage.
Can i make something like this?
template<typename T,std::size_t N>
struct storage{
typedef std::size_t size_type;
typedef T value_type;
typedef T* pointer;
typedef typename std::tr1::aligned_storage<sizeof(value_type)
,std::tr1::alignment_of<size_type>::value>::type aligned_type;
aligned_type* bos_; ///begin of storage pointer
void init(){
bos_ =
static_cast<aligned_type*>(std::malloc(sizeof(aligned_type)*N));
if(0 == bos_){
throw std::bad_alloc("storage initialization failed");
}
///is it ok? can i treat the memory as sie_type* ?
size_type* p = reinterpret_cast<size_type*>(bos_);
for (size_type i = 0; i != N; ++p){
///is it ok ? ++p goes to next memory location which is
multiple
//of both sizeof(size_type) & sizeof(value_type) ?
*p = ++i;
}
}
};

NOTE: it is ok for me to loose some memory if sizeof(T) <
sizeof(size_type)
or my bookkeeping takes more memory than value_type

Thanks
abir
7 Answers

Maxim Yegorushkin

11/11/2008 11:59:00 AM

0

On Nov 11, 6:47 am, abir <abirba...@gmail.com> wrote:
>  In my program i wan to use a certain type as both type T1 (usually
> non-pod)
>     and also T2 (usually size_t)
>
>     so an union like this doesn't work
>     template<typename T>
> union utype{
>     T v_;
>     std::size_t sz_;};
>
> utype* memory_;
> where T is
> struct nonpod{
>     int x;
>     int y;
>     nonpod(){}
>
> };
>
> I am not familiar to aligned_storage or its usage.
> Can i make something like this?

[]

You could.

Or you can take a ready-made solution: boost::variant<>.

--
Max

abir

11/11/2008 2:13:00 PM

0

On Nov 11, 4:59 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
> On Nov 11, 6:47 am, abir <abirba...@gmail.com> wrote:
>
>
>
> > In my program i wan to use a certain type as both type T1 (usually
> > non-pod)
> > and also T2 (usually size_t)
>
> > so an union like this doesn't work
> > template<typename T>
> > union utype{
> > T v_;
> > std::size_t sz_;};
>
> > utype* memory_;
> > where T is
> > struct nonpod{
> > int x;
> > int y;
> > nonpod(){}
>
> > };
>
> > I am not familiar to aligned_storage or its usage.
> > Can i make something like this?
>
> []
>
> You could.
>
> Or you can take a ready-made solution: boost::variant<>.
>
Probably i could, but i am more interested to know how that ready-
made
solution is made.

And i am rather interested to know the usage of aligned_storage &
alignment_of
Not finding enough documentation on them.
so whether the alignment_type below going to be aligned for both
value_type & size_type
typedef typename std::tr1::aligned_storage<sizeof(value_type)
,std::tr1::alignment_of<size_type>::value>::type
aligned_type;
and i am interested to have a loki style not-so-small-object allocator
(at least not smaller than size_type)
and each storage can hold more than 255 objects & guided by size_type.

Also the code had a problem
it should be
aligned_type* p = bos_;
for (size_type i = 0; i != N; ++p){
*(reinterpret_cast<size_type*>(p)) = ++i;
}

And thanks for reply.
abir
> --
> Max

Maxim Yegorushkin

11/11/2008 3:57:00 PM

0

On Nov 11, 2:13 pm, abir <abirba...@gmail.com> wrote:
> On Nov 11, 4:59 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
> wrote:
>
> > On Nov 11, 6:47 am, abir <abirba...@gmail.com> wrote:
>
> > >  In my program i wan to use a certain type as both type T1 (usually
> > > non-pod)
> > >     and also T2 (usually size_t)
>
> > >     so an union like this doesn't work
> > >     template<typename T>
> > > union utype{
> > >     T v_;
> > >     std::size_t sz_;};
>
> > > utype* memory_;
> > > where T is
> > > struct nonpod{
> > >     int x;
> > >     int y;
> > >     nonpod(){}
>
> > > };
>
> > > I am not familiar to aligned_storage or its usage.
> > > Can i make something like this?
>
> > []
>
> > You could.
>
> > Or you can take a ready-made solution: boost::variant<>.
>
> Probably i could, but i am more interested to know how that ready-
> made
> solution is made.
>
> And i am rather interested to know the usage of aligned_storage &
> alignment_of
> Not finding enough documentation on them.

You use aligned_storage<>::type as a member or a stack variable, so
that the compiler aligns it properly.

Using malloc(N * sizeof(aligned_storage<>::type)) does not guarantee
alignment in the general case. malloc() returns memory suitably
aligned for a built-in type with the largest alignment requirement
(which often is double or long double). Thus, if the alignment
requirement for aligned_storage<>::type is greater than that of a
built-in type with the largest alignment requirement, malloc() is not
directly suitable (you need to allocate more memory with malloc() and
align it manually). On the other hand, if the alignment requirement
for aligned_storage<>::type is equal to or less than that of a built-
in type with the largest alignment requirement, than you don't need
aligned_storage<>::type when using malloc(), just use the largest size
malloc(N * std::max(sizeof(nonpod), sizeof(size_t))).

> so whether the alignment_type below going to be aligned for both
> value_type & size_type
> typedef typename std::tr1::aligned_storage<sizeof(value_type)
>         ,std::tr1::alignment_of<size_type>::value>::type
> aligned_type;

aligned_type here is only guaranteed to have alignment size_type and
the size of value_type.

> and i am interested to have a loki style not-so-small-object allocator
> (at least not smaller than size_type)
> and each storage can hold more than 255 objects & guided by size_type.

I depends whether that allocator needs to support types with alignment
requirement greater than that of the built-in type with the largest
alignment requirement (align on processor cache size for example). If
it does not need to (like most allocators), than malloc() is fine and
you don't need to use aligned_storage<>::type. If it does, you don't
need aligned_storage<>::type either, because you are going to use
functions like mmap, posix_memalign() to allocate suitably aligned
memory, or manually align memory allocated with malloc().

--
Max

Larry Evans

11/11/2008 4:31:00 PM

0

On 11/11/08 08:13, abir wrote:
> On Nov 11, 4:59 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
> wrote:
>> On Nov 11, 6:47 am, abir <abirba...@gmail.com> wrote:
[snip]
>> You could.
>>
>> Or you can take a ready-made solution: boost::variant<>.
>>
> Probably i could, but i am more interested to know how that ready-
> made
> solution is made.
>
> And i am rather interested to know the usage of aligned_storage &
> alignment_of
> Not finding enough documentation on them.
> so whether the alignment_type below going to be aligned for both
> value_type & size_type
> typedef typename std::tr1::aligned_storage<sizeof(value_type)
> ,std::tr1::alignment_of<size_type>::value>::type
> aligned_type;
> and i am interested to have a loki style not-so-small-object allocator
> (at least not smaller than size_type)
> and each storage can hold more than 255 objects & guided by size_type.

Hi abir,

More than a year ago, I had a similar problem, only it involved
finding how to aligne either a tuple or a variant. I read some
references and found a solution, but I'm not sure the solution
is correct. I got no feedback either way :(

I've included a reference to the references in a boost post.
Maybe you could find them useful:

http://article.gmane.org/gmane.comp.lib.boost.devel/159260/match=ali...

Chris M. Thomasson

11/12/2008 8:10:00 AM

0


"abir" <abirbasak@gmail.com> wrote in message
news:ebe0739d-fee8-4eac-8703-c77203ec8a12@t18g2000prt.googlegroups.com...

[...]

You can usually get the alignment of a type like:
________________________________________________________________________
#include <iostream>
#include <cstddef>


template<typename T>
static std::size_t
align_of() {
struct align_of_aligner {
char m_pad;
T m_obj;
};

return offsetof(align_of_aligner, m_obj);
}


struct foo {
char c;
double a;
};


int main(void) {
std::cout << "align_of<char>() == " << align_of<char>() << std::endl;
std::cout << "align_of<short>() == " << align_of<short>() << std::endl;
std::cout << "align_of<int>() == " << align_of<int>() << std::endl;
std::cout << "align_of<long>() == " << align_of<long>() << std::endl;
std::cout << "align_of<float>() == " << align_of<float>() << std::endl;
std::cout << "align_of<double>() == " << align_of<double>() << std::endl;
std::cout << "align_of<long double>() == " << align_of<long double>() <<
std::endl;
std::cout << "align_of<struct foo>() == " << align_of<foo>() << std::endl;
return 0;
}
________________________________________________________________________




You can also forcefully align addresses by using the following simplistic
HACK:

http://groups.google.com/group/comp.programming.threads/msg/f2b1ca...
(read all, follow links...)




Chris M. Thomasson

11/12/2008 8:10:00 AM

0


"abir" <abirbasak@gmail.com> wrote in message
news:ebe0739d-fee8-4eac-8703-c77203ec8a12@t18g2000prt.googlegroups.com...

[...]

You can usually get the alignment of a type like:
________________________________________________________________________
#include <iostream>
#include <cstddef>


template<typename T>
static std::size_t
align_of() {
struct align_of_aligner {
char m_pad;
T m_obj;
};

return offsetof(align_of_aligner, m_obj);
}


struct foo {
char c;
double a;
};


int main(void) {
std::cout << "align_of<char>() == " << align_of<char>() << std::endl;
std::cout << "align_of<short>() == " << align_of<short>() << std::endl;
std::cout << "align_of<int>() == " << align_of<int>() << std::endl;
std::cout << "align_of<long>() == " << align_of<long>() << std::endl;
std::cout << "align_of<float>() == " << align_of<float>() << std::endl;
std::cout << "align_of<double>() == " << align_of<double>() << std::endl;
std::cout << "align_of<long double>() == " << align_of<long double>() <<
std::endl;
std::cout << "align_of<struct foo>() == " << align_of<foo>() << std::endl;
return 0;
}
________________________________________________________________________




You can also forcefully align addresses by using the following simplistic
HACK:

http://groups.google.com/group/comp.programming.threads/msg/f2b1ca...
(read all, follow links...)




Chris M. Thomasson

11/12/2008 8:10:00 AM

0


"abir" <abirbasak@gmail.com> wrote in message
news:ebe0739d-fee8-4eac-8703-c77203ec8a12@t18g2000prt.googlegroups.com...

[...]

You can usually get the alignment of a type like:
________________________________________________________________________
#include <iostream>
#include <cstddef>


template<typename T>
static std::size_t
align_of() {
struct align_of_aligner {
char m_pad;
T m_obj;
};

return offsetof(align_of_aligner, m_obj);
}


struct foo {
char c;
double a;
};


int main(void) {
std::cout << "align_of<char>() == " << align_of<char>() << std::endl;
std::cout << "align_of<short>() == " << align_of<short>() << std::endl;
std::cout << "align_of<int>() == " << align_of<int>() << std::endl;
std::cout << "align_of<long>() == " << align_of<long>() << std::endl;
std::cout << "align_of<float>() == " << align_of<float>() << std::endl;
std::cout << "align_of<double>() == " << align_of<double>() << std::endl;
std::cout << "align_of<long double>() == " << align_of<long double>() <<
std::endl;
std::cout << "align_of<struct foo>() == " << align_of<foo>() << std::endl;
return 0;
}
________________________________________________________________________




You can also forcefully align addresses by using the following simplistic
HACK:

http://groups.google.com/group/comp.programming.threads/msg/f2b1ca...
(read all, follow links...)