Jump to page: 1 2
Thread overview
core.runtime.GC memory alignment
Oct 27, 2013
David Nadlinger
Oct 27, 2013
Peter Alexander
Oct 27, 2013
David Nadlinger
Oct 27, 2013
Peter Alexander
Oct 27, 2013
Peter Alexander
Oct 28, 2013
Manu
Oct 27, 2013
monarch_dodra
Oct 27, 2013
John Colvin
Oct 27, 2013
monarch_dodra
Oct 27, 2013
Peter Alexander
Oct 28, 2013
Manu
Oct 28, 2013
monarch_dodra
Oct 28, 2013
David Nadlinger
Oct 29, 2013
Manu
Oct 29, 2013
growler
Oct 29, 2013
growler
Oct 29, 2013
Artur Skawina
Oct 29, 2013
growler
Oct 29, 2013
Manu
October 27, 2013
The documentation for the GC.malloc family of functions mentions that they return "an aligned block of managed memory from the garbage collector" without any further specification about what that level of alignment is supposed to be.

What do we actually want to guarantee here? "Sufficient for any built-in type"?

Note that my question is not about how the current implementation behaves, but about what the actual API guarantee should be.

David
October 27, 2013
On Sunday, 27 October 2013 at 15:49:00 UTC, David Nadlinger wrote:
> What do we actually want to guarantee here? "Sufficient for any built-in type"?

It should guarantee the same as what malloc guarantees IMO:

"The malloc() and calloc() functions return a pointer to the allocated memory that is suitably aligned for any kind of variable."

I see no reason to diverge from that.
October 27, 2013
On Sunday, 27 October 2013 at 16:19:28 UTC, Peter Alexander wrote:
> "The malloc() and calloc() functions return a pointer to the allocated memory that is suitably aligned for any kind of variable."
>
> I see no reason to diverge from that.

Welö, except for the fact that "any kind of variable" is not well-defined for a language that supports user-defined alignment restrictions:

---
struct Foo {
    align(8192) byte b;
}

template Seq(T...) { alias Seq = T; }
void main() {
    import core.memory, core.stdc.stdio, core.stdc.stdlib;
    foreach (alloc; Seq!(malloc, GC.malloc)) {
        auto mem = cast(Foo*)alloc(Foo.sizeof);
        printf("%u\n", cast(uint)(cast(size_t)mem & (Foo.alignof - 1)));
    }
}

---

David
October 27, 2013
On Sunday, 27 October 2013 at 17:53:14 UTC, David Nadlinger wrote:
> On Sunday, 27 October 2013 at 16:19:28 UTC, Peter Alexander wrote:
>> "The malloc() and calloc() functions return a pointer to the allocated memory that is suitably aligned for any kind of variable."
>>
>> I see no reason to diverge from that.
>
> Welö, except for the fact that "any kind of variable" is not well-defined for a language that supports user-defined alignment restrictions:

Correct me if I'm wrong, but my understanding is that align(N) on a member only specifies the alignment *within the struct*, i.e. the member offsets. There's no guarantee that the Foo object itself will be aligned to 8192. It's not really memory alignment.
October 27, 2013
On 10/27/13 12:51 PM, Peter Alexander wrote:
> On Sunday, 27 October 2013 at 17:53:14 UTC, David Nadlinger wrote:
>> On Sunday, 27 October 2013 at 16:19:28 UTC, Peter Alexander wrote:
>>> "The malloc() and calloc() functions return a pointer to the
>>> allocated memory that is suitably aligned for any kind of variable."
>>>
>>> I see no reason to diverge from that.
>>
>> Welö, except for the fact that "any kind of variable" is not
>> well-defined for a language that supports user-defined alignment
>> restrictions:
>
> Correct me if I'm wrong, but my understanding is that align(N) on a
> member only specifies the alignment *within the struct*, i.e. the member
> offsets. There's no guarantee that the Foo object itself will be aligned
> to 8192. It's not really memory alignment.

Yah, something like that. I found align(NNN) underspecified and underpowered for my work with allocators. As a simple matter, NNN must be a literal, not a compile-time expression. You can't even write e.g. align(size_t.alignof), which is fairly basic.


Andrei

October 27, 2013
On Sunday, 27 October 2013 at 20:30:05 UTC, Andrei Alexandrescu wrote:
> Yah, something like that. I found align(NNN) underspecified and underpowered for my work with allocators. As a simple matter, NNN must be a literal, not a compile-time expression. You can't even write e.g. align(size_t.alignof), which is fairly basic.

Yeah I noticed the literal requirement as well and thought it was quite odd...

October 27, 2013
On Sunday, 27 October 2013 at 20:30:05 UTC, Andrei Alexandrescu wrote:
> Yah, something like that. I found align(NNN) underspecified and underpowered for my work with allocators. As a simple matter, NNN must be a literal, not a compile-time expression. You can't even write e.g. align(size_t.alignof), which is fairly basic.
>
>
> Andrei

In that case, we also need to specify how alignOf works. For example:

struct S
{
    align(128) int i;
}

static assert(S.alignOf == 128);

If "align(N)" is supposed to only mean "alignement relative to the start of the struct", why the heck is S's "alignOf" 128?

Also, (but I can't double check it right now), I seem to remember that there are odd things, like "ulong.alignOf == 8", yet if you declare one on the stack, you notice it's only 4 aligned (at least, on my win32 (I think) it is...)
October 27, 2013
On Sunday, 27 October 2013 at 20:50:30 UTC, monarch_dodra wrote:
> On Sunday, 27 October 2013 at 20:30:05 UTC, Andrei Alexandrescu wrote:
>> Yah, something like that. I found align(NNN) underspecified and underpowered for my work with allocators. As a simple matter, NNN must be a literal, not a compile-time expression. You can't even write e.g. align(size_t.alignof), which is fairly basic.
>>
>>
>> Andrei

> "alignment relative to the start of the struct"

what does that even mean? Alignment means (address % alignment) == 0

what would be the use case for guaranteeing ((fieldAddress - StructAddress) % alignment) == 0 that can't be just as easily done using normal alignment
October 27, 2013
On Sunday, 27 October 2013 at 21:20:12 UTC, John Colvin wrote:
> On Sunday, 27 October 2013 at 20:50:30 UTC, monarch_dodra wrote:
>> On Sunday, 27 October 2013 at 20:30:05 UTC, Andrei Alexandrescu wrote:
>>> Yah, something like that. I found align(NNN) underspecified and underpowered for my work with allocators. As a simple matter, NNN must be a literal, not a compile-time expression. You can't even write e.g. align(size_t.alignof), which is fairly basic.
>>>
>>>
>>> Andrei
>
>> "alignment relative to the start of the struct"
>
> what does that even mean? Alignment means (address % alignment) == 0
>
> what would be the use case for guaranteeing ((fieldAddress - StructAddress) % alignment) == 0 that can't be just as easily done using normal alignment

Observation shows that that's *how* align currently behaves anyways:
http://forum.dlang.org/thread/difcpyoejpbngzpoynce@forum.dlang.org#post-nhrvixioystchhdpmakg:40forum.dlang.org

Its like its incorrectly named, and actually specifies "paking". However, the two concepts seem packed into one, resulting in some confusing semantics and bahaviors.
October 27, 2013
On Sunday, 27 October 2013 at 21:20:12 UTC, John Colvin wrote:
> On Sunday, 27 October 2013 at 20:50:30 UTC, monarch_dodra wrote:
>> On Sunday, 27 October 2013 at 20:30:05 UTC, Andrei Alexandrescu wrote:
>>> Yah, something like that. I found align(NNN) underspecified and underpowered for my work with allocators. As a simple matter, NNN must be a literal, not a compile-time expression. You can't even write e.g. align(size_t.alignof), which is fairly basic.
>>>
>>>
>>> Andrei
>
>> "alignment relative to the start of the struct"
>
> what does that even mean? Alignment means (address % alignment) == 0

Alignment also means alignment within an object. It's more commonly referred to as "padding" but it's a form of alignment.


> what would be the use case for guaranteeing ((fieldAddress - StructAddress) % alignment) == 0 that can't be just as easily done using normal alignment

Usually it's done when you are reading binary files that are in some particular format that may or may not pack data in the same way that you'd get from normal alignment.


> If "align(N)" is supposed to only mean "alignement relative to the start of the struct", why the heck is S's "alignOf" 128?
>
> Also, (but I can't double check it right now), I seem to remember that there are odd things, like "ulong.alignOf == 8", yet if you declare one on the stack, you notice it's only 4 aligned (at least, on my win32 (I think) it is...)

I believe .alignof also refers to structure alignment, it doesn't guarantee alignment in memory or on the stack (as you've discovered).
« First   ‹ Prev
1 2