[En-Nut-Discussion] ARM GCC 4.4 Alignment Problems
Harald Kipp
harald.kipp at egnite.de
Fri Apr 2 17:04:04 CEST 2010
Hi Bernd,
It's always a pleasure to see you jumping in when things become a bit
complicated.
On 01.04.2010 20:06, Bernd Walter wrote:
> I'm not so much a fan about missaligned data.
Who is? ;-)
> In almost every case it is avoidable without much trouble.
> One of the most annoying points with network data is the 6 bytes long
> ethernet header, which usually garanties missaligned IP headers, but
> usually this is avoided by setting RX buffers at a 2 byte offset or
> copying the data before parsing if HW require 32bit aligned DMA RX
> buffers - AT91SAM7X should be happy with 2 byte offset, AT91RM9200
> are not and require copying.
Using a 2 byte offset is indeed an option worth to be evaluated.
Copying, however, is something that really consumes CPU power.
> Packed on ARM has different reasons - older ARM CPUs required bytes
> and 16bit words to be on the same alignment because they had to
> mask bytes out from 32bit memory operations and therefor structs
> containing 3 bytes are 4 bytes long, so that an array of those structs
> always start the same members at the same 32bit offset.
Not a real problem, but of course additional instructions are required
compared to 32-bit aligned elements.
> Usually this isn't a problem and it is also Ok with C-standards, but
> parsing network data with structs can be a problem.
> Since we don't need ABI compatibility with older ARM systems it
> shouldn't be a problem to use -mstructure-size-boundary=8 (bits)
> and don't use packed.
This option will reduce the total size of a structure, but it will not
pack its members.
typedef struct __attribute__((packed)) ether_header {
uint8_t ether_dhost[ETHER_ADDR_LEN];
uint8_t ether_shost[ETHER_ADDR_LEN];
uint16_t ether_type;
} ETHERHDR;
struct __attribute__((packed)) frame {
ETHERHDR hdr;
uint32_t data[8];
};
ETHERHDR is 14 bytes and struct frame is 8 * 4 + 14 = 46 bytes.
When removing packed and instead compiling with
-mstructure-size-boundary=8, then ETHERHDR is still 14 bytes only, but
struct frame will grow by 2 bytes, because data[] will become aligned.
The problem is not the size of structures, but the alignment of their
members.
Please correct me if I'm wrong, I'm just evaluating this stuff.
Harald
More information about the En-Nut-Discussion
mailing list