[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-devel] Curious struct packing issue - is it GCC?

From: address@hidden
Subject: Re: [lwip-devel] Curious struct packing issue - is it GCC?
Date: Sat, 25 Apr 2009 14:06:53 +0200
User-agent: Thunderbird (Macintosh/20090302)

Bill Auerbach wrote:

I’m trying to inline SMEMCPY. I see it’s used with lengths only of 4, 6, 18, 20 and 28. By inlining it with byte copies, I see over a 5% increase in outbound bandwidth (that’s all I’m focused on right now). As has come up this week, the call to memcpy to copy 4 or 6 bytes is very silly (IMO).

Shouldn't the compiler do that inlining job for you? Isn't there an option for gcc for that?

I thought I would copy u16_t in half the copies since either everything is u32_t aligned for my processor (NIOS II – GCC as mentioned) or **should** be u16_t aligned for IP related items.

Why that? For which reason should stack-internal data be 16-bit aligned?

Everything **is** u16_t aligned except one item – hwaddr in struct netif. Netif does **not** include packing around its definition, but curiously, it **does** include packed struct members.

The struct netif is an lwIP-internal struct and thus does not need to be packed. The only structs that need packing are those used in protocol headers/data, since their layout is determined by the network/protocol.

As such, I don't think you can rely on all data being u16_t aligned to achieve good performance: every struct member of an non-packed struct should be aligned as it is required - thus, a char array can always be non aligned! After all, you still have the alignment-problem if setting LWIP_NETIF_HOSTNAME to 1.

Have I found a problem in that GCC carried the included packed struct override through the remainder of the netif struct?

I'm not sure I understand you here: The packed struct members you are talking about are the IP-addresses, right? Is there anything unaligned after the 3 addresses? If so, that would be a bug, yes.

If I delete hwaddr_len from struct netif and then replace the only 2 uses of it in dhcp.c (netif->hwaddr_len ) with ETHARP_HWADDR_LEN, the remainder of netif is properly aligned.

Since we use ETHARP_HWADDR_LEN everywhere else in lwIP, why keep it in the netif, especially if it’s used only in DHCP 2 times?

Did I understand you correctly that you want to remove the u8_t to get hwaddr aligned? That might work now, but I don't think every developer changing that struct will remember such a subtle alignment issue...

Aside from that, we explicitly *don't* use ETHERP_HWADDR_LEN throughout the stack, only in places that are ethernet-related (etharp.c, ethernetif.c, example port ethernet drivers). This is necessary to use the stack in non-ethernet environments!

|..] I think this can be changed to MEMCPY since I don’t think any compiler will inline a 28 byte copy. And this call is only in the icmp_dest_unreach function.

Hm, I guess that's up to the compiler: But since it doesn't know the alignemnt of src and dst, it probably won't... Is there any disadvantage in keeping the SMEMCPY?

To sum it up, I think the idea of that copy define is quite handy, but it should by all means be optional and keep working even if some developers change structs to bad alignment.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]