Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Since we have event_get_struct_event_size(), we need event_get_struct_event_align() #650

Closed
rod1gin opened this issue Jun 21, 2018 · 6 comments

Comments

@rod1gin
Copy link

rod1gin commented Jun 21, 2018

We know, how many bytes must be allocated for 'struct event', but we don't know, how these bytes must be aligned. We can use alignof(max_align_t), but:

  1. this is inaccurate
  2. this leads to waste of 8 bytes for each 'struct event'
@azat
Copy link
Member

azat commented Jun 21, 2018

Can you elaborate what for?

@rod1gin
Copy link
Author

rod1gin commented Jun 21, 2018

What to do?

To the file 'event.c', below definition of 'event_get_struct_event_size':

#if defined(STDC_VERSION)
#if STDC_VERSION >= 201112L
size_t
event_get_struct_event_align(void)
{
return _Alignof(struct event);
}
#endif
#elif defined(__cplusplus)
#if __cplusplus >= 201103L
size_t
event_get_struct_event_align(void)
{
return alignof(struct event);
}
#endif
#endif

To the file 'event.h', below declaration of 'event_get_struct_event_size':

/**
Return the alignof(struct event) that the Libevent library was compiled
with.

This function is not defined if the library was compiled by too old compiler
(without support of C11 standard of C language or C++11 standard of C++
language).
*/
size_t event_get_struct_event_align(void);

@azat
Copy link
Member

azat commented Jun 21, 2018

I was asking about why do you need this? What for you need alignment?

@rod1gin
Copy link
Author

rod1gin commented Jun 22, 2018

The purpose is exactly the same as for the 'event_get_struct_event_size' function.

Typical server. Thousands of simultaneous TCP connections. A connection appears, works not long time and disappears. The program allocates for each connection exactly one block of dynamic memory. This block contains miscellaneous data, associated with the connection (lets name it 'struct
Connection'), and two 'struct event' (for reading and for writing).

(We can allocate each 'struct event' in separate block of dynamic memory by means of 'event_new' function. But this is sligtly slower and requires slightly more memory. This leads to bigger fragmentation of dynamic memory. This complicates the program if we want carefully handle lack of memory. And so on.)

We can place first 'struct event' into address 'begin'+sizeof(Connection) and second into address 'begin'+sizeof(Connection)+event_get_struct_event_size(). But this is wrong way, because structures will be misaligned. In Intel processors this leads to productivity penalty. In non-intel this can leads to memory access violation.

Right way is to place first 'struct event' into address 'begin' + (((sizeof(Connection) + A - 1) / A) * A), where A is alignment requirement for 'struct event' (I assume that 'struct event' is not over-aligned).

On 64-bit Intel processors A is typically equal to 8 if 'struct event' does not contains 'long double' fields, or to 16 if it contains. On 32-bit Intel it can be equal to 4, 8 or 16. Theoretically, it can be less than 4 if 'struct event' contains only short/char fields, or greater than 16 if 'struct event' is over-aligned.

@azat
Copy link
Member

azat commented Oct 28, 2018

So you are talking about some kind of slab allocator.

We can place first 'struct event' into address 'begin'+sizeof(Connection) and second into address 'begin'+sizeof(Connection)+event_get_struct_event_size(). But this is wrong way, because structures will be misaligned.

Why? sizeof(struct event) already includes alignment.

In Intel processors this leads to productivity penalty.

Well I'm pretty sure that penalty is not that huge like 20 years ago.
And I just verified it and I did not see any difference on my core i7 for aligned vs non-aligned accesses.

In non-intel this can leads to memory access violation.

I guess you mean on non-amd64/x86

So either I missing something or we do not need to introduce event_get_struct_event_align()

For now I'm closing it, but if you still disagree, please reopen.

@azat azat closed this as completed Oct 28, 2018
@ploxiln
Copy link
Contributor

ploxiln commented Oct 28, 2018

You can just always align to 8 bytes - this is easy and cheap. This is what most malloc() implementations do btw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants