Page 1 of 2

xQueue between cores takes long time

Posted: Fri May 05, 2023 5:37 am
by yoko911
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,

Re: xQueue between cores takes long time

Posted: Fri May 05, 2023 8:42 am
by ESP_Sprite
What is your code? Are you calling taskYIELD_FROM_ISR if xQueueSendFromISR sets pxHigherPriorityTaskWoken?

Re: xQueue between cores takes long time

Posted: Fri May 05, 2023 3:41 pm
by yoko911
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");
        }
     }

Re: xQueue between cores takes long time

Posted: Fri May 05, 2023 7:08 pm
by MicroController
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);
        	...

Re: xQueue between cores takes long time

Posted: Fri May 05, 2023 7:24 pm
by MicroController
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.

Re: xQueue between cores takes long time

Posted: Sat May 06, 2023 3:04 am
by yoko911
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

Re: xQueue between cores takes long time

Posted: Sat May 06, 2023 6:08 am
by yoko911
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,

:(

Re: xQueue between cores takes long time

Posted: Sat May 06, 2023 4:16 pm
by MicroController
Hmm, interesting.
If even a higer tick rate doesn't do anything...

Out of ideas here :-\

Re: xQueue between cores takes long time

Posted: Sun May 07, 2023 7:54 am
by ESP_Sprite
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.

Re: xQueue between cores takes long time

Posted: Tue May 09, 2023 10:29 pm
by felixcollins
You might have more luck asking over at the freertos forum https://forums.freertos.org/