multithreadingmulticorenanoframework

Can I dedicate a task to the second core of an ESP32 with nanoFramework?


I've been looking at examples on how to assign a task/function to one of the specific cores available on the ESP32.

The examples I found are mainly in C++ for Arduino.

It uses the function xTaskCreatedPinnedToCore(,,,0) or xTaskCreatedPinnedToCore(,,,1) to pin a task to a specific core.

Is there an equivalent in the nanoFramework or is this something that is automatically handled by the Thread class?

I've read this blog around multi threading, and it doesn't mention anything about jumping cores, instead it mentions running it in a round and robin way.

I tested it out with a small app and it works great, however as it doesn't truly run in a concurrent way I was wondering if I could dedicate a process to the 1st(0th) or 2nd(1st) core?

Test Code:

 public static void Main()
        {
            new Thread(() =>
            {
                PrimCalcBadly badCalc = new PrimCalcBadly();
                badCalc.DoCalc("first thread");
            }).Start();

           //new Thread(() =>
           //{
           //    PrimCalcBadly badCalc = new PrimCalcBadly();
           //    badCalc.DoCalc("second thread");
           //}).Start();

            Thread.Sleep(Timeout.Infinite);
        }

        class PrimCalcBadly
            {
            public void DoCalc(string calName) {
                Debug.WriteLine($"start {calName}");
                while (true)
                {
                    var sDate = DateTime.UtcNow;
                    for (int a = 2; a <= 1000; a++)
                    {
                        for (int b = 2; b <= 1000; b++)
                        {
                            if (a != b && a % b == 0)
                            {
                                break;
                            }
                        }
                    }
                    var eDate = DateTime.UtcNow;
                    var ts = TimeSpan.FromTicks(eDate.Ticks - sDate.Ticks);
                    Debug.WriteLine($"calculation for {calName} --> {ts.TotalSeconds}");
                }
            }
        }

If I only run 1 instance of the calculation it takes around 2 seconds to complete execution and start again.

Output from debug window:

start first thread
calculation for first thread --> 2.020124999
calculation for first thread --> 2.020197

If I run 2 instances of the calculations it takes 4 seconds. Output from debug window:

start first thread
start second thread
calculation for first thread --> 4.74040799
calculation for second thread --> 4.04035
calculation for first thread --> 4.040268
calculation for second thread --> 4.040204999

If I run 3 it takes 6 seconds etc...

start first thread
start second thread
start third thread
calculation for first thread --> 7.26084799
calculation for second thread --> 6.66085599
calculation for third thread --> 6.020959999
calculation for first thread --> 6.06095
calculation for second thread --> 6.060862999
calculation for third thread --> 6.060842

Solution

  • Just like on full .NET, you there is no way to control which core runs a particular thread. If you're concerned that this is not taking advantage of 2 core devices, don't worry. On ESP32 devices that have them, the work is split between cores, like running the CLR and execution engine on one, Wi-Fi and network stuff on another, driver specific tasks, secondary tasks that execute long running operations and such.