__attribute__((packed)) is a GNU C++ extension tell the compiler not to not to align the data structure to the machine word. Using this attribute make it easy serialize the content of the structure in a platform independent way.

For example,

struct Aligned {
  u_int64_t a;
  char b;
};

On 64-bit machine (word length 8), sizeof(Aligned) is 8 (assuming sizeof(int) is 4)). Here structure is padded with 3 bytes to align it to the word size.

struct NonAligned {
  int a;
  char b;
};

On 64-bit machine (word length 8), sizeof(Aligned) is 5 (assuming sizeof(int) is 4)). Here there is not padding added.

For the non-aligned structure, compiler generate extra code to adjust the memcpy operation. I tried the following code.

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>

struct NonAligned {
  int a;
  char b;
} __attribute__ ((packed));

struct Aligned {
  int a;
  char b;
};

int main() {
  NonAligned a;
  Aligned b;

  char buf[10];
  size_t c = 1000000000;
  {
    struct timeval start, end;
    gettimeofday(&start, NULL);
    for (size_t i = 0; i < c; ++i) {
      memcpy(&buf, &a, sizeof(a));
    }
    gettimeofday(&end, NULL);
    suseconds_t t = ( (end.tv_usec + end.tv_sec * 1000000) - (start.tv_usec + start.tv_sec * 1000000) );
    printf( "total time: %u\n", t);
  }

  {
    struct timeval start, end;
    gettimeofday(&start, NULL);
    for (size_t i = 0; i < c; ++i) {
      memcpy(&buf, &b, sizeof(b));
    }
    gettimeofday(&end, NULL);
    suseconds_t t = ( (end.tv_usec + end.tv_sec * 1000000) - (start.tv_usec + start.tv_sec * 1000000) );
    printf( "total time: %u\n", t);
  }

}

The above code produced the following output on my Mac air.

total time: 4487688
total time: 2565614

Copying non-aligned structure is 42% slower than the aligned structure.

Advertisements