Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocating initialized, aligned memory

I'm writing a program (in C++) in which I need to allocate arrays whose starting addresses should be aligned with the cache line size. When I allocate these arrays I also want the memory initialized to zero.

Right now I have it working using the posix_memalign function. This works well for getting memory aligned arrays but the arrays are uninitilized. Is there a better function I can use to zero out the arrays when I initialize them or do I just have to settle for writing a separate loop to do it for me?

like image 620
martega Avatar asked Dec 17 '12 04:12

martega


People also ask

Does malloc allocate aligned memory?

3.6 Allocating Aligned Memory Blocks. The address of a block returned by malloc or realloc in GNU systems is always a multiple of eight (or sixteen on 64-bit systems). If you need a block whose address is a multiple of a higher power of two than that, use aligned_alloc or posix_memalign .

What does it mean for memory to be aligned?

Alignment refers to the arrangement of data in memory, and specifically deals with the issue of accessing data as proper units of information from main memory. First we must conceptualize main memory as a contiguous block of consecutive memory locations. Each location contains a fixed number of bits.

What is the alignment of malloc?

new and malloc, by default, align address to 8 bytes (x86) or 16 bytes (x64), which is the optimal for most complex data.

Is malloc 16 byte aligned?

The GNU documentation states that malloc is aligned to 16 byte multiples on 64 bit systems.


1 Answers

Just call memset on the block. Make sure you don't cast the pointer to a type that's expensive to set (like char *) before calling memset. Since your pointer will be aligned, make sure that information isn't hidden from the compiler.

Update: To clarify my point about not hiding alignment, compare:

char* mem_demo_1(char *j)
{ // *BAD* compiler cannot tell pointer alignment, must test
    memset(j, 0, 64);
    return j;
}

char* mem_demo_2(void)
{ // *GOOD* compiler can tell pointer alignment
    char * j = malloc(64);
    memset(j, 0, 64);
    return j;
}

With GCC, mem_demo_1 compiles to 60 lines of assembly while mem_demo_2 compiles to 20. The performance difference is also huge.

like image 75
David Schwartz Avatar answered Sep 21 '22 05:09

David Schwartz