xQueue between cores takes long time

yoko911
Posts: 6
Joined: Fri Feb 24, 2023 12:42 am

xQueue between cores takes long time

Postby yoko911 » Fri May 05, 2023 5:37 am

I have a heavy processing function (DSP) that I want to perform in parallel, so I have pinned a 'task' task to Core0 and 'offload' task to Core1,

The processing is on a buffer in memory of 300k Bytes, so I am sending a pointer to the center of the buffer using xQueueSend, so that the offload task in Core1 can start processing from the middle, this should decrease my processing time by almost half, however, I am finding that the xQueueSend calls are taking around 10ms as per the timestamp

below logs:
1798 ms: Core1 is ready waiting for xQueue
25208ms Core0 is ready to start processing and sends a message to Core1
25218ms: 10 seconds later, Core1 returns from xQueueReceive

here the logs:

Code: Select all

W (1798)   offload: waiting for message...
I (25208)   task: Sending message xQueueSend Core 0
W (25218) offload: message received xQueueReceive Core 1
I (25218)   task: Start process,  Core 0
I (25228)   offload: Start process, Core 1
What could be causing this? is it normal for xQueue to take 10ms?

Or do I have memory collision? because both cores call the same function to process the data, the function just requires a pointer to memory and length,

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: xQueue between cores takes long time

Postby ESP_Sprite » Fri May 05, 2023 8:42 am

What is your code? Are you calling taskYIELD_FROM_ISR if xQueueSendFromISR sets pxHigherPriorityTaskWoken?

yoko911
Posts: 6
Joined: Fri Feb 24, 2023 12:42 am

Re: xQueue between cores takes long time

Postby yoko911 » Fri May 05, 2023 3:41 pm

it is pretty straight forward, as you will see, both cores are calling

Code: Select all

DarkChannel()
, so the other thing I was thinking is that maybe memory collision?

here are the main snippets:

From main()

Code: Select all

main() 
{
    mat_split_task_handle = xTaskCreateStaticPinnedToCore(dehaze_task,              // Function Ptr
                                                        "Task",              // Name
                                                        STACK_SIZE0,                // Stack size
                                                        nullptr,                    // Parameter
                                                        configMAX_PRIORITIES - 2,   // Prio
                                                        xStack0,                    // Static stack array
                                                        &xTaskBuffer0,              // Static TCB
                                                        0);                         // Core 0
    
    offload_task_handle = xTaskCreateStaticPinnedToCore(dehaze_offload_task,        // Function Ptr
                                                        "Offload",             // Name
                                                        STACK_SIZE1,                // Stack size
                                                        nullptr,                    // Parameter
                                                        configMAX_PRIORITIES - 2,   // Prio
                                                        xStack1,                    // Static stack array
                                                        &xTaskBuffer1,              // Static TCB
                                                        1);      
 }
From Task

Code: Select all

    printf("Sending message");
    message_tx->src      = &src_B;
    xQueueSend( xDehazeToOffload_Queue, ( void * ) &message_tx, ( TickType_t ) 0 );

    // Process 
    DarkChannel(src_T);

    printf("Waiting Rendezvous");   
    uxBits = xEventGroupWaitBits(xMatEvents,       // Event group handler
                                 MAT_SPLIT_EVENT,  // Event to wait for
                                 pdTRUE,           // clear bits
                                 pdFALSE,          // do not wait for all, either event suffice
                                 portMAX_DELAY);   // wait forever
    
    printf("Rendezvous received");   
From offload task

Code: Select all

 while(1)
    {
        ESP_LOGW(TAG, "waiting for message...");
        if (xQueueReceive(xDehazeToOffload_Queue, (void *)&message_rx, OFFLOAD_EVENT_WAIT_MS) == pdTRUE) 
        {
            ESP_LOGW(TAG, "message received...");
            // offload 
            Mat         *src   = message_rx->src;
            DarkChannel(*src);

            ESP_LOGW(TAG, "Sending event");
            xEventGroupSetBits(xMatEvents, MAT_SPLIT_EVENT);
            ESP_LOGW(TAG, "Event sent");
        }
     }

MicroController
Posts: 1688
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: xQueue between cores takes long time

Postby MicroController » Fri May 05, 2023 7:08 pm

Code looks ok, I believe.
So, another line of thought: While "memory collision" is not a thing, you use logging/printf (concurrently) in both tasks. Logging is a) kinda expensive and b) a potential point of congestion because all logging output needs to be serialized out over one physical channel.

I suggest to verify your observation as follows:

Code: Select all

#include "esp_timer.h" // For esp_timer_get_time()

// Global:
volatile int64_t timestamp;
Task:

Code: Select all

timestamp = esp_timer_get_time();
xQueueSend( xDehazeToOffload_Queue, ( void * ) &message_tx, ( TickType_t ) 0 );
Offload task:

Code: Select all

        if (xQueueReceive(xDehazeToOffload_Queue, (void *)&message_rx, OFFLOAD_EVENT_WAIT_MS) == pdTRUE) 
        {
        	int64_t now = esp_timer_get_time();
        	ESP_LOGI(TAG, "Message received after %" PRIi64 " micro-seconds", now-timestamp);
        	...

MicroController
Posts: 1688
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: xQueue between cores takes long time

Postby MicroController » Fri May 05, 2023 7:24 pm

P.S.: For the most efficient coordination between the two tasks, I recommend looking into direct-to-task notifications as an alternative to both the queue and the event group in this case.

yoko911
Posts: 6
Joined: Fri Feb 24, 2023 12:42 am

Re: xQueue between cores takes long time

Postby yoko911 » Sat May 06, 2023 3:04 am

I have tried adding the timestamp to the message, but still seems slow, now I get 7ms from when sending the message up to Core1, and starting the DarkChannel process there is a difference of 20ms:

Code: Select all

I (25178) dehaze: Sending message, Core 0 ts: 23521941 micro-seconds
W (25188) Mat_offload: message received...Core 1 ts: 23528978 micro-seconds
I (25188) dehaze: Start DarkChannel, Free heap: 2432399 bytes Core 0 ts: 23528990 micro-seconds
W (25198) Mat_offload: id:        911
I (25208) dehaze: Start DarkChannel, Free heap: 2432399 bytes Core 1 ts: 23550376 micro-seconds
will try the thread notification instead

yoko911
Posts: 6
Joined: Fri Feb 24, 2023 12:42 am

Re: xQueue between cores takes long time

Postby yoko911 » Sat May 06, 2023 6:08 am

Changed notification method to

Code: Select all

xTaskGenericNotify
but still getting 10ms between sending the notification and receiving it on the other core :/ also, increased tick frequency from 100Hz to 1000Hz,

:(

MicroController
Posts: 1688
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: xQueue between cores takes long time

Postby MicroController » Sat May 06, 2023 4:16 pm

Hmm, interesting.
If even a higer tick rate doesn't do anything...

Out of ideas here :-\

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: xQueue between cores takes long time

Postby ESP_Sprite » Sun May 07, 2023 7:54 am

Can you post (more of) your code (again)? The snippets of code that you changed later on don't really make it much clearer to see what's going on.

felixcollins
Posts: 125
Joined: Fri May 24, 2019 2:02 am

Re: xQueue between cores takes long time

Postby felixcollins » Tue May 09, 2023 10:29 pm

You might have more luck asking over at the freertos forum https://forums.freertos.org/

Who is online

Users browsing this forum: Google [Bot] and 109 guests