lwip-devel
[Top][All Lists]
Advanced

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

Re: [lwip-devel] How to estimate heap memory usage (TCP case)


From: Simon Goldschmidt
Subject: Re: [lwip-devel] How to estimate heap memory usage (TCP case)
Date: Tue, 13 Mar 2012 08:58:15 +0100

narke <address@hidden> wrote:
> > Keep in mind that to the MSS, various protocol headers plus struct pbuf
> is also allocated from the heap. That alone would require at least
> ~5.9KByte heap.
> 
> Thanks for your reply Simon.  Did you get the number 5.9KB from my
> TCP_MSS value?  How did you calculate this magic number?

I wrote 'at least' because I'm not absolutely sure this is correct. However, my 
calculation was:

- TCP_MSS is 1388 and TCP_SND_BUF is 4 * TCP_MSS
- When using full segments (every segment has 1388 bytes of TCP data in it), 
you can thus send 4 segments
- Every segment has TCP headers (20 bytes), IPv4 headers (20 bytes) and 
ethernet headers (14 or 16 bytes) plus the pbuf struct (which is 16 bytes on 
most platforms) Add memory alignment to that (e.g. 8 bytes worst case for 
MEM_ALIGNMENT==4) and you have 80 bytes overhead per segment.
-> 4 segments (1388 bytes + 80 bytes overhead) = 5872 bytes

However, since you turned off nagle, you might end up with many small segments 
sent out, so you have to add 80 bytes for all those small segments, not for 
every TCP_MSS bytes.

> > Without using TCP_OVERSIZE, every write gets its own pbuf, so if you
> call tcp_write with a size != MSS, you risk losing another 72 byte for every
> call of tcp_write that doesn't start a new segment. Added to that, the heap
> needs its own organization structures, so you cannot allocate the full byte
> count configured with MEM_SIZE.
> 
> I am not quite understand the TCP_OVERSIZE.  My current setting is
> TCP_OVERSIZE = TCP_MSS. What does it mean?

That doesn't really make sense with nagle disabled. TCP_OVERSIZE assumes that 
nagle is enabled (the default) so most segments sent out will have the size of 
MSS. Now the old code created a pbuf for every call to tcp_write, which 
resulted in a linked list of pbufs per segment when calling tcp_write with 
small chunks of data. TCP_OVERSIZE instead allocates a pbuf of the configured 
size (TCP_MSS in your case) and fills in data into that single pbuf over 
multiple calls of tcp_write. It tracks the usage and trunkates the pbuf on 
sending if it isn't full. That way, we avoid pbuf chains with nagle enabled.

However, with nagle disabled, this results in every single segment you send out 
taking ~1468 bytes (1388+80) off the heap (and remember with nagle disabled, 
every call to tcp_output leads to sending everything in pcb->unsent). So with 
nagle disabled, I'd set TCP_OVERSIZE to 0.

> What's
> the idea TCP_OVERSIZE setting to archive minimum memory use without
> worrying about my segment get fragmented?

Now I don't understand what you mean by a fragmented segment, but the best way 
to ensure a segment only consists of one single pbuf while still not wasting 
memory is to only call tcp_write once per segment (so that would mean you have 
to gather all necessary data in an extra buffer before passing it to lwIP).

> Yes, this I understand. I will separably count my other mem_alloc() uses.

Also, make sure you don't use PBUF_RAM for RX pbufs - use PBUF_POOL instead.

Simon
-- 
NEU: FreePhone 3-fach-Flat mit kostenlosem Smartphone!                          
        
Jetzt informieren: http://mobile.1und1.de/?ac=OM.PW.PW003K20328T7073a



reply via email to

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