[PATCH] elf: dl-minimal malloc needs to respect fundamental alignment
Florian Weimer
fweimer@redhat.com
Thu Jun 23 17:54:00 GMT 2016
On 06/23/2016 07:02 PM, Joseph Myers wrote:
> On Thu, 23 Jun 2016, Florian Weimer wrote:
>
>> As far as I know, we know match or exceed the C11 max_align_t requirements.
>> What we cannot do is to bump max_align_t alignment because it affects ABI.
>
> That's not obvious to me. It shouldn't affect the ABI of any function in
> glibc, for example; it's not the sort of type you embed in other
> structures.
I'm more worried about something using _Alignas (max_align_t), affecting
struct layout.
> Increasing max_align_t to cover _Float128 (for 32-bit x86 as
> the sole affected case) is a question I left open in my GCC _FloatN /
> _FloatNx patch posting (not included in that patch, potentially relevant
> for a followup); that issue properly applies to _Decimal128 as well.
If we hurry up, we could bump max_align_t on i386, true. The type and
its implied promise is still fairly new, after all.
But a path towards increasing the fundamental alignment from time to
time is less clear to me.
We also interpret the max_align_t requirement strictly in our malloc in
the sense that we also apply it to small allocations. Other mallocs
will happily return blocks with just 8-byte alignment on x86_64, where
_Alignof (max_align_t) is 16. Maybe this something we could address in
the definition of max_align_t in the C standard, but its definition is
already very confusing.
Surprisingly the impact on i386 wouldn't even be *that* severe. The
minimum allocation size would still be 12 (for a total chunk size of
16). The size range from 13 to 20 is affected most prominently: The
total chunk size would go from 24 bytes to 32 bytes, an increase of one
third. But this is also the largest such increase, the subsequent ones
are progressively smaller:
def roundup(value, align):
return (value + align - 1) / align * align
def chunk_size(pointer_size, align, object_size):
minimum_chunk_size = roundup(4 * pointer_size, align)
size = roundup(object_size + pointer_size, align)
return max(minimum_chunk_size, size)
print "size old new increase"
for size in range(0, 65):
old_size = chunk_size(4, 8, size)
new_size = chunk_size(4, 16, size)
increase = (float(new_size) / old_size - 1) * 100
print " %2d %2d %2d %8.2f" % (
size, old_size, new_size, increase)
size old new increase
0 16 16 0.00
1 16 16 0.00
2 16 16 0.00
3 16 16 0.00
4 16 16 0.00
5 16 16 0.00
6 16 16 0.00
7 16 16 0.00
8 16 16 0.00
9 16 16 0.00
10 16 16 0.00
11 16 16 0.00
12 16 16 0.00
13 24 32 33.33
14 24 32 33.33
15 24 32 33.33
16 24 32 33.33
17 24 32 33.33
18 24 32 33.33
19 24 32 33.33
20 24 32 33.33
21 32 32 0.00
22 32 32 0.00
23 32 32 0.00
24 32 32 0.00
25 32 32 0.00
26 32 32 0.00
27 32 32 0.00
28 32 32 0.00
29 40 48 20.00
30 40 48 20.00
31 40 48 20.00
32 40 48 20.00
Â…
glibc malloc is not based on size groups for allocations, but fewer,
more granular sizes will still help to reduce fragmentation somewhat.
Maybe we should just make the change, document the increased alignment,
and have GCC change their definition of max_align-t?
The overhead would be more pronounced if we go from 16 bytes to 32 bytes
alignment on 64-bit architectures.
Florian
More information about the Libc-alpha
mailing list