lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] TCP performance in receiving


From: Craig Graham
Subject: Re: [lwip-users] TCP performance in receiving
Date: Mon, 11 Oct 2004 10:44:01 +0100
User-agent: KMail/1.6

I just ran a few tests using Atte's approach to the issues with tcp_recved(),
and the results are astonishing - using libCurl to do HTTP transfers over 
ethernet from an apache server on the local subnet, lwip's download 
performance goes up massive enormously (based on time taken to download a 
large (several MB) file). I also tryed Bo-Er's approach of reducing the 
TCP_FAST_INTERVAL, which gives some improvement in download rate, but nowhere 
near as noticable as the mod to tcp_recved().

Here's the comparison:
                                 Time       %performance
Stock 1.0.0 (with cvs mods)      74s        100% (baseline)
TCP_FAST_INTERVAL=100s           69s        107%
tcp_recved() mod                 29s        255%
tcp_recved() + TCP_FAST_INTERVAL 26.7s      277%

Anyway, as Atte didn't actually post his modified version of tcp_recved(), 
here's my interpretation (used to get the above figures):

void
tcp_recved(struct tcp_pcb *pcb, u16_t len)
{
  int ackNow=0;
  
  if ((u32_t)pcb->rcv_wnd + len > TCP_WND) {
    pcb->rcv_wnd = TCP_WND;
  } else {
    pcb->rcv_wnd += len;
    ackNow=1;
  }
  if (!(pcb->flags & TF_ACK_DELAY) &&
     !(pcb->flags & TF_ACK_NOW)) {
    /*
     * We send an ACK here (if one is not already pending, hence
     * the above tests) as tcp_recved() implies that the application
     * has processed some data, and so we can open the receiver's
     * window to allow more to be transmitted.  This could result in
     * two ACKs being sent for each received packet in some limited cases
     * (where the application is only receiving data, and is slow to
     * process it) but it is necessary to guarantee that the sender can
     * continue to transmit.
     */
    tcp_ack(pcb);
  }else if((pcb->flags & TF_ACK_DELAY)&&(ackNow)){
    //++cg[11/10/2004]: I think this is what Atte Kojo was talking about
    tcp_ack(pcb);
  }
}

Laters,
Craig.

On Monday 11 October 2004 03:49, Wei Bo-Er (Jason) wrote:
> Hi all,
>
> Thanks for your help.
>
> I think what Atte said is more close to what I meet. In my case,I saw that
> TCP receiving worked well at first. But it got slow down after receivied
> several packets. It seems to be that we can't directly send ack via
> tcp_recved but only can send it via another packet arrived or tcp_fasttmr.
> So it gets slow down after sender has sent TCP_WND size of data.
>
> Regards,
>
> Bo-Er
>
>   K.J. Mansley wrote:
>   > I thought that the stack should, if asked to send an ACK when one has
>   > already been delayed, send a dedicated packet out at that point.  i.e.
>   > There should only be one outstanding delayed acknowledgement at once.
>   > This would mean that if as in your case the stack is only receiving
>   > data, it would send ACKs for every other packet, rather than wait 250ms
>   > as you report.
>   >
>   > The implementation of tcp_ack() backs this up:
>   >
>   > #define tcp_ack(pcb)     if((pcb)->flags & TF_ACK_DELAY) { \
>   >                             (pcb)->flags &= ~TF_ACK_DELAY; \
>   >                             (pcb)->flags |= TF_ACK_NOW; \
>   >                             tcp_output(pcb); \
>   >                          } else { \
>   >                             (pcb)->flags |= TF_ACK_DELAY; \
>   >                          }
>   >
>   > If the TF_ACK_DELAY flag is already set, it is cleared, and TF_ACK_NOW
>   > set instead.  The call to tcp_output() should then dispatch the
>   > acknowledgement straight away.
>   >
>   > However, as this doesn't match what you are seeing, there might be
>   > something wrong.  I'm not sure what though.
>
>   This is because tcp_recved() only does an ack if there are no acks
>   pending (delayed or otherwise):
>
>   if (!(pcb->flags & TF_ACK_DELAY) &&
>        !(pcb->flags & TF_ACK_NOW)) {
>        /* ... comment deleted ... */
>        tcp_ack(pcb);
>   }
>
>   This effectively nullifies the tests in tcp_ack() in this case. I
>   resolved this problem (probably not very cleanly) by adding an extra
>   else to above test that sends out an ack if there is already a
>   TF_ACK_DELAY pending on the pcb and the receive window is big enough.
>
>   I had the same problem when doing an application that only receives a
>   huge amount of data without sending out anything.
>
>   - Atte
>
>   --
>   GARLIC GUM IS NOT FUNNY
>   GARLIC GUM IS NOT FUNNY
>   GARLIC GUM IS NOT FUNNY
>   GARLIC GUM IS NOT FUNNY
>
>   Bart Simpson on chalkboard in episode 7G13
>
>
>   _______________________________________________
>   lwip-users mailing list
>   address@hidden
>   http://lists.nongnu.org/mailman/listinfo/lwip-users




reply via email to

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