malloc()和对齐 [英] malloc() and alignment

查看:84
本文介绍了malloc()和对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力了解设计决策中有一个(好吧,

当然三个,但基本上是一个)分配函数返回

a指针保证对于任何类型都要对齐。


在我看来,这里有灵活性和

效率之间的权衡。在64位机器上很容易想象,例如,长的
或指针需要在8字节边界处对齐。然后,如果

你有一个包含大量字符串的程序,那么

你可能会为每一个丢失7个字节的内存! (我猜

字符总是可以进行任何对齐)


我会说通过例如三个
$可以大大改善情况b $ b类型的分配函数:

1)malloc,泛型分配器,与当前malloc相同

2)malloc_char,返回一个只保证对齐的指针

char

3)malloc_int,但同样适用于int。


这样的事情是不是有一个很好的理由标准?并且

没有任何实现似乎也有这样的设施。

解决方案

Fr ************ @ googlemail.com 写道:


我一直在试图理解设计决定是否有一个(好吧,

当然是三个,但实质上是一个)分配函数返回

a指针保证可以对齐任何类型。


在我看来,灵活性和

效率之间存在权衡。在64位机器上很容易想象,例如,长的
或指针需要在8字节边界处对齐。然后,如果

你有一个包含大量字符串的程序,那么

你可能会为每一个丢失7个字节的内存! (我猜

字符总是可以进行任何对齐)



电位更多,这完全取决于系统如何分解可用内存。 />

在过去几十年里我所做的每一个项目中,我已经添加了分析器作为测试工具的
。在每种情况下,

分配大小主要是机器字大小的倍数。

大多数分配用于结构。


我会说,通过提供三种类型的分配函数可以大大改善情况:

1)malloc,泛型分配器,与当前malloc相同

2)malloc_char,返回一个只保证对齐的指针

char

3)malloc_int,同样但是对于int。



想象一下跟踪指针的类型所带来的痛苦,以及

它能够和不能被施展的内容。
< blockquote class =post_quotes>
有没有一个很好的理由这样的东西不在标准中?并且

没有任何实现似乎也有这样的设施。



没有人想要它吗?


-

Ian Collins。


Fr ************ @ googlemail.com 写道:


我已经一直试图理解设计决定有一个(好吧,

三个当然,但基本上一个)分配函数返回

a指针保证为任何类型对齐。


在我看来,在灵活性和

效率之间存在权衡。在64位机器上很容易想象,例如,长的
或指针需要在8字节边界处对齐。然后,如果

你有一个包含大量字符串的程序,那么

你可能会为每一个丢失7个字节的内存! (我猜

字符总是可以进行任何对齐)


我会说通过例如三个
$可以大大改善情况b $ b类型的分配函数:

1)malloc,泛型分配器,与当前malloc相同

2)malloc_char,返回一个只保证对齐的指针

char

3)malloc_int,但同样适用于int。


这样的事情是不是有一个很好的理由标准?并且

没有任何实现似乎也有这样的设施。



实现自己的malloc()

等可能是有益的。熟悉一些问题。在K& R中有一个相当简单的版本(原来的;我想它也是在K& R II中也是b $ b但是我不知道当然,你可以用

作为起点。


你可能会发现的一件事是malloc()经常

预留的空间比所要求的多一点,空间中可以存放一些内务处理数据。这些数据通常需要至少与size_t一样多的空间,或许更多。如果管家数据本身正确对齐,这肯定会最方便

,这反过来会影响整个

膨胀的对齐方式块。如果你已经需要对齐size_t足够的

,那么提供最严格的

对齐通常没什么困难。


当然,并非所有分配器都遵循简单的

K& R风格。例如,有些人通过允许地址本身

暗示管理:如果地址位于

内存,它指的是这个大小的对象,我们不需要明确存储大小的
。 (这是为什么realloc()

在缩小区域时可能会失败的一个原因。)这样的分配器可能会使b / b
能够在没有过多的情况下进行单字节分配/>
罚款,但我在实践中实际看到的那些已经使用了

a更大的最小分配。大小。


很久以前,c.l.c。争论malloc(1)是否需要提供

内存,这些内存已正确对齐,例如,在sizeof(double)> 1的常见

情况下。一方坚持标准的字母

:对于任何类型,返回的值必须正确对齐

,就是这样。另一方指出,

任何试图在1字节区域存储双精度都会调用

未定义的行为,因此没有严格符合的程序
$对于小额拨款而言,b $ b可能会导致更宽松的对齐;

的差异没有任何区别。如果我没记错的话,严格的标准建筑工人会把这一天带走,但更多的是因为体积而不是美元。


-

Eric Sosman
es ***** @ acm- dot-org.inva 盖子


Eric Sosman< es ***** @ acm-dot-org.invalidwrites:

Fr ************ @ googlemail.com 写道:



[...]


>我会说通过具有三种类型的分配函数可以大大改善情况:
1)malloc,泛型分配器,与当前malloc相同
2 )malloc_char,返回一个只保证对齐的指针
char
3)malloc_int,同样但是对于int。
有没有一个很好的理由这样的东西不在标准中?并且
没有任何实现似乎也有这样的设施。



[...]


>

你可能会发现的一件事是malloc()经常

预留的空间比所要求的多一点,空间中它可以存放一些内务数据。这些数据通常需要至少与size_t一样多的空间,或许更多。如果管家数据本身正确对齐,这肯定会最方便

,这反过来会影响整个

膨胀的对齐方式块。如果你已经需要对齐size_t足够的

,那么提供最严格的

对齐通常并不困难。



另外,回到第一次设计malloc()时,很可能

最严格的对齐要求可能只有2个字节,或者4

(想想PDP-11和朋友),所以malloc()的对齐要求

不会浪费太多空间。


[...]


很久以前,clc争论malloc(1)是否需要提供

内存,这些内存已正确对齐,例如,在sizeof(double)> 1的常见

情况下。一方坚持标准的字母

:对于任何类型,返回的值必须正确对齐

,就是这样。另一方指出,

任何试图在1字节区域存储双精度都会调用

未定义的行为,因此没有严格符合的程序
$对于小额拨款而言,b $ b可能会导致更宽松的对齐;

的差异没有任何区别。如果我没记错的话,严格的标准建筑工人会把这一天带走,但更多的是因为体积而不是美元。



辩论中的另一个论点是,仅指定一个未对齐的

指针值会调用未定义的行为。例如,这个:


void * ptr = malloc(1);

断言(ptr!= NULL);

double * dptr = ptr;


必须正常工作; dptr'的值必须与

的任何双重对象的地址不同,并且您必须能够使用" =="来检测它。或

"!="。如果将未对齐的指针值分配给double *会导致

陷阱,这意味着malloc(1)的结果必须正确

对齐。


另一方面,如果将未对齐的指针值分配给

double *不会导致陷阱(直到您尝试取消引用它),那么

一个实现可以让malloc(1)返回一个

未对齐指针;它可能会违反标准,但是很难发现

违规行为。


-

Keith Thompson(The_Other_Keith ) ks***@mib.org < http://www.ghoti.net/~kst>

圣地亚哥超级计算机中心< *< http://users.sdsc.edu/~kst>

我们必须做点什么。这是事情。因此,我们必须这样做。

- Antony Jay和Jonathan Lynn,是部长


I''ve been trying to understand the design decision to have one (well,
three of course, but essentially one) allocation function that returns
a pointer guaranteed to be aligned for any type.

It seems to me that there''s a tradeoff here between flexibility and
efficiency. It''s easy to imagine on a 64-bit machine that, say, a long
or a pointer would need to be aligned at an 8-byte boundary. Then if
you have a program with a large number of strings, for example, then
you''d potentially be losing 7 bytes of memory for each one! (I guess
chars can always take any alignment)

I''d say the situation would be greatly improved by having eg three
types of allocation function:
1) malloc, generic allocator, same as current malloc
2) malloc_char, returns a pointer only guaranteed to be aligned for
char
3) malloc_int, same but for int.

Is there a good reason something like this isn''t in the Standard? And
no implementations seem to have a facility like this either.

解决方案

Fr************@googlemail.com wrote:

I''ve been trying to understand the design decision to have one (well,
three of course, but essentially one) allocation function that returns
a pointer guaranteed to be aligned for any type.

It seems to me that there''s a tradeoff here between flexibility and
efficiency. It''s easy to imagine on a 64-bit machine that, say, a long
or a pointer would need to be aligned at an 8-byte boundary. Then if
you have a program with a large number of strings, for example, then
you''d potentially be losing 7 bytes of memory for each one! (I guess
chars can always take any alignment)

Potentialy more, it all depends how the system breaks down available memory.

On every project I''ve worked on over the past couple of decades, I''ve
added profiling allocator as a testing tool. In every case the
allocation sizes where predominantly multiples of the machine word size.
Most allocations were for structures.

I''d say the situation would be greatly improved by having eg three
types of allocation function:
1) malloc, generic allocator, same as current malloc
2) malloc_char, returns a pointer only guaranteed to be aligned for
char
3) malloc_int, same but for int.

Imagine the pain involved in keeping track of what type a pointer is and
what it can and can not be cast to.

Is there a good reason something like this isn''t in the Standard? And
no implementations seem to have a facility like this either.

No one wants it?

--
Ian Collins.


Fr************@googlemail.com wrote:

I''ve been trying to understand the design decision to have one (well,
three of course, but essentially one) allocation function that returns
a pointer guaranteed to be aligned for any type.

It seems to me that there''s a tradeoff here between flexibility and
efficiency. It''s easy to imagine on a 64-bit machine that, say, a long
or a pointer would need to be aligned at an 8-byte boundary. Then if
you have a program with a large number of strings, for example, then
you''d potentially be losing 7 bytes of memory for each one! (I guess
chars can always take any alignment)

I''d say the situation would be greatly improved by having eg three
types of allocation function:
1) malloc, generic allocator, same as current malloc
2) malloc_char, returns a pointer only guaranteed to be aligned for
char
3) malloc_int, same but for int.

Is there a good reason something like this isn''t in the Standard? And
no implementations seem to have a facility like this either.

It might be instructive to implement your own malloc()
et al. to gain familiarity with some of the issues. There''s
a fairly simple version in K&R (the original; I imagine it''s
also in K&R II but I don''t know for sure) that you could use
as a starting point.

One thing you''ll probably discover is that malloc() often
reserves a little more space than is requested, space in which
it can park some housekeeping data. That data typically takes
at least as much space as a size_t, perhaps more. It''s surely
most convenient if the housekeeping data itself is properly
aligned, which in turn influences the alignment of the entire
inflated chunk. And if you already need alignment sufficient
for a size_t, it''s usually no hardship to provide "strictest"
alignment.

Of course, not all allocators follow the straightforward
K&R style. Some, for example, avoid storing housekeeping data
along with every allocation by allowing the address itself to
imply the housekeeping: If the address is in THIS region of
memory, it refers to an object of THAT size and we need not
store the size explicitly. (This is one reason why realloc()
might fail when shrinking an area.) Such an allocator might
be able to dish out single-byte allocations without undue
penalties, but those I''ve actually seen in practice have used
a larger "minimum allocation" size.

Long ago, c.l.c. debated whether malloc(1) needed to provide
memory that was properly aligned for double, say, in the common
situation where sizeof(double)>1. One side stuck to the letter
of the Standard: the returned value had to be properly aligned
for any type, and that was that. The other side pointed out that
any attempt to store a double in the 1-byte region would invoke
undefined behavior anyhow, hence no strictly conforming program
could run afoul of looser alignment for small allocations; the
difference made no difference. If I recall correctly, the strict
Standard constructionists carried the day, but it was more due
to volume than to virtue.

--
Eric Sosman
es*****@acm-dot-org.invalid


Eric Sosman <es*****@acm-dot-org.invalidwrites:

Fr************@googlemail.com wrote:

[...]

>I''d say the situation would be greatly improved by having eg three
types of allocation function:
1) malloc, generic allocator, same as current malloc
2) malloc_char, returns a pointer only guaranteed to be aligned for
char
3) malloc_int, same but for int.
Is there a good reason something like this isn''t in the Standard? And
no implementations seem to have a facility like this either.

[...]

>
One thing you''ll probably discover is that malloc() often
reserves a little more space than is requested, space in which
it can park some housekeeping data. That data typically takes
at least as much space as a size_t, perhaps more. It''s surely
most convenient if the housekeeping data itself is properly
aligned, which in turn influences the alignment of the entire
inflated chunk. And if you already need alignment sufficient
for a size_t, it''s usually no hardship to provide "strictest"
alignment.

Also, back when malloc() was first designed, it''s likely that the
strictest alignment requirement possible was just 2 bytes, or maybe 4
(think PDP-11 and friends), so malloc()''s alignment requirement
wouldn''t have wasted much space.

[...]

Long ago, c.l.c. debated whether malloc(1) needed to provide
memory that was properly aligned for double, say, in the common
situation where sizeof(double)>1. One side stuck to the letter
of the Standard: the returned value had to be properly aligned
for any type, and that was that. The other side pointed out that
any attempt to store a double in the 1-byte region would invoke
undefined behavior anyhow, hence no strictly conforming program
could run afoul of looser alignment for small allocations; the
difference made no difference. If I recall correctly, the strict
Standard constructionists carried the day, but it was more due
to volume than to virtue.

Another argument in that debate is that just assigning a misaligned
pointer value invokes undefined behavior. For example, this:

void *ptr = malloc(1);
assert(ptr != NULL);
double *dptr = ptr;

must work properly; dptr''s value must be distinct from the address of
any double object, and you must be able to detect this using "==" or
"!=". If assigning a misaligned pointer value to a double* causes a
trap, this implies that the result of malloc(1) must be properly
aligned.

If, on the other hand, assigning a misaligned pointer value to a
double* doesn''t cause a trap (until you try to dereference it), then
an implementation could get away with having malloc(1) return a
misaligned pointer; it arguably would violate the standard, but the
violation would be difficult to detect.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


这篇关于malloc()和对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆