Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
643 views
in Technique[技术] by (71.8m points)

c - Memory alignment of arrays

I am having trouble aligning memory for DMA transfer on the Cell processor. I need the last 4 bits of an address to be 0.

I have 4 arrays of unsigned int where each element must be aligned in memory so that its (hex) adress ends with a zero.

E.g.

int main()
{
    size_t i;

    static unsigned int a[2] __attribute__ ((aligned (16)));
    static unsigned int b[2] __attribute__ ((aligned (16)));
    static unsigned int c[2] __attribute__ ((aligned (16)));
    static unsigned int d[2] __attribute__ ((aligned (16)));

    for (i = 0; i < 2; ++i) {
        printf("a[%u] = %p
", &a[i]);
        printf("b[%u] = %p
", &b[i]);
        printf("c[%u] = %p
", &c[i]);
        printf("d[%u] = %p
", &d[i]);
    }

    return 0;
}

Output:

a[0] = 0x10010b60
b[0] = 0x10010b50
c[0] = 0x10010b40
d[0] = 0x10010b30
a[1] = 0x10010b64
b[1] = 0x10010b54
c[1] = 0x10010b44
d[1] = 0x10010b34

The problem here is that the 2nd element of each array doesn't seem to be 16-bit aligned (their address' end with a 4).

I need the addresses to look like this:

a[0] = 0xXXXXXXX0
b[0] = 0xXXXXXXX0
c[0] = 0xXXXXXXX0
d[0] = 0xXXXXXXX0
a[1] = 0xXXXXXXX0
b[1] = 0xXXXXXXX0
c[1] = 0xXXXXXXX0
d[1] = 0xXXXXXXX0
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The alignment attribute specifies the alignment of variables or structure fields, not single array elements. See Specifying Attributes of Variables for details.

If you always want to align two integers together, you can define a structure

struct dma_transfer {
    unsigned int e0 __attribute__ ((aligned (16)));
    unsigned int e1 __attribute__ ((aligned (16)));
};

This aligns the elements on 16 byte boundaries.

int main(int argc, char **argv)
{
    static struct dma_transfer a;
    static unsigned int b[2];

    printf("a.e0 = %p
", &a.e0);
    printf("a.e1 = %p
", &a.e1);
    printf("b[0] = %p
", &b[0]);
    printf("b[1] = %p
", &b[1]);

    return 0;
}

gives, e.g.

a.e0 = 0x601060
a.e1 = 0x601070
b[0] = 0x601080
b[1] = 0x601084

But this means also, that you have holes between the two integer values. On a 32 bit system, you will have

| int 4 bytes | hole 12 bytes |
| int 4 bytes | hole 12 bytes |


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...