Changes between Version 20 and Version 21 of PortableRrdFormat


Ignore:
Timestamp:
Jun 26, 2007, 8:21:02 AM (15 years ago)
Author:
oetiker
Comment:

added struct alignemenet test

Legend:

Unmodified
Added
Removed
Modified
  • PortableRrdFormat

    v20 v21  
    270270 * struct members are aligned to either 32 bit or 64 bit boundaries.
    271271
    272 Below is an example of a the memory layout of several simple structs, made up from integers (32 bit) and doubles (64 bit).
    273 
    274 {{{
    275 32 bit (16 byte) : IIII.DDDD.DDDD.IIII
    276 64 bit (24 byte) : IIII ~~~~.DDDD DDDD.IIII ~~~~
    277 
    278 32 bit (12 byte) : IIII.IIII.IIII
    279 64 bit (12 byte) : IIII IIII.IIII
    280 
    281 32 bit (16 byte) : IIII.IIII.DDDD.DDDD.IIII.IIII
    282 64 bit (24 byte) : IIII IIII.DDDD DDDD.IIII IIII
    283 }}}
    284 
    285 This means, that in order to produce a portable data format, structs must be laid out such that they are aligned the same, on 32 and 64 bit systems.
    286 
     272The following little program tests how structs get aligned by your compiler/os/hw.
     273
     274{{{
     275#!c
     276
     277#include <stdio.h>
     278#include <string.h>
     279#include <inttypes.h>
     280
     281typedef enum IDEAS {
     282    ID_ONE = 0, ID_TWO, ID_THREE, ID_FOUR
     283} IDEAS;
     284
     285
     286typedef struct FORMATa {
     287    char      c1[5];
     288    uint32_t  i1;
     289    double    f1;
     290    uint32_t  i2;
     291    double    f2;
     292    uint64_t  l1;
     293    IDEAS     e1;
     294} FORMATa;
     295
     296typedef struct FORMATb {
     297    char      c1[8];   
     298    uint32_t  i1;
     299    uint32_t  i2;
     300    double    f1; 
     301    double    f2;
     302    uint64_t  l1;
     303    IDEAS     e1;
     304} FORMATb;
     305
     306typedef union OVERLAYa {
     307    uint8_t   c[sizeof(FORMATa)];
     308    FORMATa   f;
     309} OVERLAYa;
     310
     311typedef union OVERLAYb {
     312    uint8_t   c[sizeof(FORMATb)];
     313    FORMATb   f;
     314} OVERLAYb;
     315
     316int main(
     317    int argc,
     318    char *argv[])
     319{
     320    uint32_t  i;
     321
     322    OVERLAYa  sta;
     323    OVERLAYb  stb;
     324 
     325    for (i = 0; i < sizeof(OVERLAYa); i++) {
     326        sta.c[i] = 0x88;
     327    };
     328    strcpy(sta.f.c1, "012");
     329    sta.f.i1 = 123456789;
     330    sta.f.f1 = 123456789e123;
     331    sta.f.f2 = 123456789e123;
     332    sta.f.i2 = 123456789;
     333    sta.f.e1 = ID_TWO;
     334    sta.f.l1 = 123456789;
     335
     336    printf("struct test non-aligned:\n");
     337    for (i = 0; i < sizeof(OVERLAYa); i++) {
     338        printf(" %02x", sta.c[i]);
     339        if (i % 4 == 3)
     340            printf("  ");
     341        if (i % 8 == 7)
     342            printf("\n");
     343    };
     344    printf("\n\n");
     345
     346    for (i = 0; i < sizeof(OVERLAYb); i++) {
     347        stb.c[i] = 0x88;
     348    };
     349      strcpy(stb.f.c1, "012");
     350    stb.f.i1 = 123456789;
     351    stb.f.f1 = 123456789e123;
     352    stb.f.f2 = 123456789e123;
     353    stb.f.i2 = 123456789;
     354    stb.f.e1 = ID_TWO;
     355    stb.f.l1 = 123456789;
     356
     357    printf("struct test aligned:\n");
     358    for (i = 0; i < sizeof(OVERLAYb); i++) {
     359        printf(" %02x", stb.c[i]);
     360        if (i % 4 == 3)
     361            printf("  ");
     362        if (i % 8 == 7)
     363            printf("\n");
     364    };
     365    printf("\n\n");
     366
     367    return 0;
     368}
     369}}}                                                                 
     370
     371I have run this on a number of different architectures. The memory is initialized to 0x88 so all places where you see 88 the memory has not been touched. In the first line, this is to be expected since the char array is 8 bytes long but I copy only a 3 byte null terminated string into it. If you can add yours this would be great.
     372
     373On Linux x86/32bit gcc-4.1 everything is tightly packed.
     374{{{
     375struct test non-aligned:
     376 30 31 32 00   88 88 88 88 
     377 15 cd 5b 07   81 ee 46 95 
     378 5e 43 26 5b   15 cd 5b 07 
     379 81 ee 46 95   5e 43 26 5b 
     380 15 cd 5b 07   00 00 00 00 
     381 01 00 00 00 
     382
     383struct test aligned:
     384 30 31 32 00   88 88 88 88 
     385 15 cd 5b 07   15 cd 5b 07 
     386 81 ee 46 95   5e 43 26 5b 
     387 81 ee 46 95   5e 43 26 5b 
     388 15 cd 5b 07   00 00 00 00 
     389 01 00 00 00 
     390}}}
     391
     392On Linux x86/64bit gcc-4.1 things are aligned to 64bit bounderies when
     393{{{
     394struct test non-aligned:
     395 30 31 32 00   88 88 88 88 
     396 15 cd 5b 07   88 88 88 88 
     397 81 ee 46 95   5e 43 26 5b 
     398 15 cd 5b 07   88 88 88 88 
     399 81 ee 46 95   5e 43 26 5b 
     400 15 cd 5b 07   00 00 00 00 
     401 01 00 00 00   88 88 88 88 
     402
     403
     404struct test aligned:
     405 30 31 32 00   88 88 88 88 
     406 15 cd 5b 07   15 cd 5b 07 
     407 81 ee 46 95   5e 43 26 5b 
     408 81 ee 46 95   5e 43 26 5b 
     409 15 cd 5b 07   00 00 00 00 
     410 01 00 00 00   88 88 88 88 
     411}}}
     412
     413
     414solaris sparc 32bit as well as 64bit gcc-3.1.
     415Interestingly enough, the sun people align to 64bit bounderies in 32bit as well as 64bit mode.
     416{{{
     417struct test non-aligned:
     418 30 31 32 00   88 88 88 88 
     419 07 5b cd 15   88 88 88 88 
     420 5b 26 43 5e   95 46 ee 81 
     421 07 5b cd 15   88 88 88 88 
     422 5b 26 43 5e   95 46 ee 81 
     423 00 00 00 00   07 5b cd 15 
     424 00 00 00 01   88 88 88 88 
     425
     426struct test aligned:
     427 30 31 32 00   88 88 88 88 
     428 07 5b cd 15   07 5b cd 15 
     429 5b 26 43 5e   95 46 ee 81 
     430 5b 26 43 5e   95 46 ee 81 
     431 00 00 00 00   07 5b cd 15 
     432 00 00 00 01   88 88 88 88 
     433}}}
     434
     435This means, that if the struct members are layed out properly, they will occupy the same amount of memory everywhere.
    287436
    288437== Longs and Integers ==

NOTE: The content of this website is accessible with any browser. The graphical design though relies completely on CSS2 styles. If you see this text, this means that your browser does not support CSS2. Consider upgrading to a standard conformant browser like Mozilla Firefox or Opera but also Apple's Safari or KDE's Konqueror for example. It may also be that you are looking at a mirror page which did not copy the CSS for this page. Or if some pictu res are missing, then the mirror may not have picked up the contents of the inc directory.