• AVR Freaks

AnsweredHot!TCP Task performance issues due to artificial delay time

Author
David Green
Junior Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/04/10 07:57:13
  • Location: 0
  • Status: offline
2020/03/18 05:18:11 (permalink)
0

TCP Task performance issues due to artificial delay time

Hi there,

I am using: FreeRTOS 10, Harmony 2.6, PIC32MZ2048EFM144, HTTP Net, NetPres, TCP

I have several requirements concerning the web server:
* "quite a lot" multiple connections possible
* website should load within a specific time

Due to these contrains, I have to limit the socket-buffers of each socket. Normally I would have increased the socket buffer sizes to get more performance.

But there is one thing that bothers me: The tcp-stack-task/tcp-task/http net-task each have a artificial pause time. The TASK_RATE or TICK_RATE (for example TCPIP_TCP_TASK_TICK_RATE).
These values are used to trigger timers that trigger the worker-functions of each component.
Unfortunatly, I cannot set these values to zero, so that the task-components run every task-loop of the FreeRTOS task. The TCP-Stack will not work then.

As you can see in the attached wireshark trace, the communication is paused for about the set TICK_RATE (here: 5 ms), after each buffer has been sent. If I increase the TICK_RATE, the marked gaps increase too.

So my question is:
Can I change the way the TCP-Module calls the task-components?
Is it maybe safe to call TCPIP_TCP_Tick() TCPIP_TCP_Process(), etc. manually in my FreeRTOS-Loop?
Is there maybe a build in way to change this behavior?


Attached Image(s)

#1
rainad
Moderator
  • Total Posts : 1293
  • Reward points : 0
  • Joined: 2009/05/01 13:39:25
  • Location: 0
  • Status: offline
Re: TCP Task performance issues due to artificial delay time 2020/03/18 11:38:48 (permalink)
0
Yes, the vTaskDelay() that's present in each generated task will have a big impact on performance, even if you use the minimum value, which is 1ms.
The TCP_IP stack supports signalling. So, what you can do is to create a thread, register signal handlers for the stack - you can do that for the sockets too - and the signal handler just releases a sync object (semaphore, event flag) that your created thread waits upon. So, when the thread wakes up it will call TCPIP_Stack_Task() and then go back to sleep. This should increase performance.
No direct mechanism like this exists for NET_PRES. However, you can try either executing the NET_PRES_Task when yo execute TCPIP Task or you can add signals to the NET_PRES sockets that you use.
 
#2
David Green
Junior Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/04/10 07:57:13
  • Location: 0
  • Status: offline
Re: TCP Task performance issues due to artificial delay time 2020/03/19 01:17:09 (permalink)
0
Hi rainad,

thanks for the quick answer!

The vTaksDelays of the Tasks I have already eliminated. I managed to set the TCP and NetPres Tasks to a priority of 0 so they can run contantly aside the idle task (I am using time slicing). It has its drawbacks but works so far quite well.

What I meant was the following settings:

#define TCPIP_STACK_TICK_RATE 1
#define TCPIP_HTTP_NET_TASK_RATE 1
#define TCPIP_TCP_TASK_TICK_RATE 1

They seem to delay the components by the set value. It looks like the components are driven by timer-callbacks which are called regulary with the configured values.
For example (tcp_ipmanager.c):


// create the stack tick timer
static bool _TCPIPStackCreateTimer(void)
{

    tcpip_stack_tickH = SYS_TMR_CallbackPeriodic(TCPIP_STACK_TICK_RATE, 0, _TCPIP_STACK_TickHandler);
    if(tcpip_stack_tickH != SYS_TMR_HANDLE_INVALID)
    {
        uint32_t sysRes = SYS_TMR_TickCounterFrequencyGet();
        uint32_t rateMs = ((sysRes * TCPIP_STACK_TICK_RATE) + 999 )/1000;    // round up
        stackTaskRate = (rateMs * 1000) / sysRes;
        // SYS_TMR_CallbackPeriodicSetRate(tcpip_stack_tickH, rateMs);
        return true;
    }


    SYS_ERROR_PRINT(SYS_ERROR_ERROR, TCPIP_STACK_HDR_MESSAGE "Tick registration failed: %d\r\n", TCPIP_STACK_TICK_RATE);
    return false;

}


And these are the delays I see in the wireshark trace.
#3
rainad
Moderator
  • Total Posts : 1293
  • Reward points : 0
  • Joined: 2009/05/01 13:39:25
  • Location: 0
  • Status: offline
Re: TCP Task performance issues due to artificial delay time 2020/03/20 11:31:45 (permalink)
5 (1)
All modules - starting with the low level modules in the stack: UDP, TCP, etc. but also HTTP, etc. - process 2 different types of signals: RX events and timeout events.
So, if a socket has received data it will be signaled immediately and the corresponding thread should wake up immediately and process. 
The time ticks are just for maintaining the state machines, for example, checking timeouts when there's no traffic.
I think that these ticks should not impact your processing. 
You can enable the notifications and intercept the signals, and check the delay between a packet received and when the signal occurs. It should be minimal.
Of course, the main dispatcher, which is done in the TCPIP_STACK_Task() needs to run first. But this one uses signaling too.
 
 
 
#4
David Green
Junior Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/04/10 07:57:13
  • Location: 0
  • Status: offline
Re: TCP Task performance issues due to artificial delay time 2020/03/24 06:32:01 (permalink)
0
I think we are talking about two different scenarios (I am talking about outgoing data, you about incoming data) wink: wink

I have to elaborate:
I am using the "dynamic variables" to send custom data (jsons) from the PIC to the client. These can get quite long (10k and longer).
So the data buffer is full and needs to be split into multiple messages, since the socket tx-buffer is much smaller.
It looks like just one TX-socket buffer is send for each timeslot (set by TCPIP_STACK_TICK_RATE).

To reproduce, I have just tried the Harmony example "web_server_nvm_mpfs" with the PIC32MZ EFM StarterKit:

* If you set the TCPIP_HTTP_TASK_RATE to 33 you can see several delays in the range from 10 to 33ms when fetching a html page. (all_30ms.png)
* If you set the TCPIP_HTTP_TASK_RATE to 1, you see delays up to 1ms (all_1ms.png)
* If the function TCPIP_HTTP_Process() is called within the superloop SYS_Tasks() the delays get much smaller. (all_http_net_manual_call.png)

This might not matter when the transfered data is small, but when your website is 5MB big and other, frequently transfered data is 10k and larger, these delays really hurt.

So the delay (at least for TCPIP_HTTP_TASK_RATE) limits the throughput. It looks like the other delays are not as influential as I thought.
I will call the tcpip_http_process() function in my web-task for now (unless you know a reason not to do that).
 
Edit: I just saw that the example is using HTTP not HTTPNet... The way the tasks are called look similar though.
post edited by David Green - 2020/03/24 06:45:06

Attached Image(s)

#5
rainad
Moderator
  • Total Posts : 1293
  • Reward points : 0
  • Joined: 2009/05/01 13:39:25
  • Location: 0
  • Status: offline
Re: TCP Task performance issues due to artificial delay time 2020/03/24 14:51:48 (permalink)
0
Yes, I was thinking about the RX data flow :)
More exactly, about the fact that when there's incoming data, the HTTP module will start looking into that data 'immediately' and that's what will call the application to send its data too.
But that's just the start. I now understand your problem. Indeed, if the amount of data to output is big, the fact that HTTP asks for data periodically will have an impact.
- The 1st thing that will have an effect is the socket buffer size. You should increase those TX buffers for HTTP and you'll notice results immediately. What size do the socket buffers have now in your app?
- Lowering the TCPIP_STACK task rate to 1 ms will also help.
If we assume that you can transfer 40 Mbps with a HTTP socket that has enough TX space (an average throughput) this corresponds to 5 MBps i.e. 5 KB/ms. Meaning that if you have the socket buffer > 5 KB, you can keep it full all the time, with the 1 ms period. That's it without the need to call the HTTP task outside the stack.
 
I'll think how the TX side signalling mechanism can be used.
For example, the socket will tell you that it has transmitted its data  and can transmit more.
Probably this signal could be used as well, besides the RX events, to speed up the TX side.
It's pretty similar with what we're doing for the RX side and the signals already exist, so it shouldn't be too difficult to add them in.
 
 
 
 
#6
David Green
Junior Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/04/10 07:57:13
  • Location: 0
  • Status: offline
Re: TCP Task performance issues due to artificial delay time 2020/03/25 08:47:38 (permalink)
0
My socket buffers are 1536 bytes in size (both rx and tx). I would love to make them larger, but I need to support quite a lot of "concurrent" open sockets so I do not have the RAM to enlargen the socket buffers.
 
The idea with a TX side signaling sounds good. Of course it would be ideal if the TCP-Stack realizes itself that is still has data to send and avoids the delay time in that case.
#7
rainad
Moderator
  • Total Posts : 1293
  • Reward points : 0
  • Joined: 2009/05/01 13:39:25
  • Location: 0
  • Status: offline
Re: TCP Task performance issues due to artificial delay time 2020/03/26 07:13:33 (permalink) ☼ Best Answerby David Green 2020/03/26 08:40:37
5 (2)
I'll create an internal issue request to add the TX signalling as well for HTTP (and probably other modules too).
It will add to the existing RX + timeout signals, so yes, the stack will indicate that it needs attention.
 
#8
David Green
Junior Member
  • Total Posts : 38
  • Reward points : 0
  • Joined: 2017/04/10 07:57:13
  • Location: 0
  • Status: offline
Re: TCP Task performance issues due to artificial delay time 2020/03/26 08:40:15 (permalink)
5 (1)
Thank you, rainad!
#9
Jump to:
© 2020 APG vNext Commercial Version 4.5