Forum Rule: Always post complete source code & details to reproduce any issue!
Page 16 of 16 FirstFirst ... 6 14 15 16
Results 376 to 382 of 382

Thread: Teensy 3.x multithreading library first release

  1. #376
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    495
    Is it possible to set a thread priority using this library, such that a higher priority thread will preempt a lower priority thread?

  2. #377
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,008
    Me again Brian.

    Been digging into c++ threads again for another project and I don't think c++11 or c++14 implements a setPriority command, so I doubt that TeensyThreads does it either. I think it is supported in Windows or Linux implementations of threads. So unless fritas implements in his library don't think the current version has a command to setPriority.

  3. #378
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,059
    I didn't see it in my following - github doesn't address Priority - except first lock blocked item will be called next.

    Adding selectivity to time order queueing would really impact overhead of what seems to be a simple thread switcher.

  4. #379
    Junior Member
    Join Date
    Aug 2018
    Posts
    12
    I just wanted to say thanks for this library. It's solved a problem with my POV wheel project. You see, It's spinning about 900rpm (planning to go faster), and has 32 APA102 leds divided up into 360 segments per rotation. I was struggling with too much CPU use during the "render" phase, that was causing skips of some of the output segments. Even overclocked to 120, 144 or 168Mhz wasn't enough. I'm using a simple double-buffer. Rendering to one one buffer while the other is read for outputs to the LEDs. Some of the animations and graphics I'm rendering at about 5fps needed more CPU cycles than I had to spare between segment outputs. I was doing every trick in the book to speed up the rendering, like having a ATAN, SIN and COS lookup table. A lookup table for converstion of a polar coord to a cartsean coord. That sort of thing. I was even starting to plan out my own "half-assed" threading scheme. All I needed was to break up the rendering phase into chunks until it was done, then flip the buffer. After lots of failed "Arduino" searches, I found this thread.. and Voila!! I can take as long as I need on my rendering thread now, and almost no impact on the output thread at all. I even removed the COS and SIN lookup tables and everything is working perfectly.

    I still have couple of math precision issues to work out, and the fact that I have to be sure to leave enough clock-ticks for the FastLED library to send it's output. But, other than that, it's looking good!!

  5. #380
    I helped someone with a project yesterday and had a look at TeensyThreads and found some flaws in it. I hope this can help.

    1. The way FPU registers are saved and restored unconditionally are very inefficient. Cortex uses lazy stacking and all you have to do is: (google it for technical info)

    // save
    tst r14, #0x10
    it eq
    vstmdbeq r0!, {s16-s31}

    // restore
    tst r14, #0x10
    it eq
    vldmiaeq r0!, {s16-s31}

    2. The threads_svcall_isr interrupt should have the lowest priority (0xff) on the system. Or it’s impossible to yield from any interrupt with lower or same priority.

    3. The use of noinline attributes makes no sens. An advice: Always develop and test you code the optimizer on full throttle -O3 (don’t use lto as default). You can always turn it off if you want to debug. It’s always easier discover and correct the errors right away and the optimizer is normally not destroying anything if done correctly. (Be carefull, the Internet is floating with a lot of corrupt examples on inline asm)

    4. Interrupts are disabled longer than necessary, it is recommended to use BASEPRI instead of disabling all interrupts. But that change is up to PJRC or it will break compatibility. Freertos has done a decent job, look at a small file under Source/portable/GCC/ARM_CM4F/port.c
    Last edited by Jacob.Schultz; 01-09-2019 at 08:30 AM.

  6. #381
    Senior Member
    Join Date
    Sep 2013
    Location
    Boston, MA
    Posts
    111
    Thank you for looking at the code and pointing out these very interesting optimizations. It has been over 2 years since I wrote this code so I'm don't recall many of the specifics. Can you create a patch or a change in git for #1 and #2?

    For #3, I presume you are referring to the noinline Threads::Mutex::lock/unlock? I don't recall the details but there was a problem with one of the compiler settings. Perhaps when link-time optimizations are enabled? I'll have to read through my notes. Maybe it's not relevant any more.

    For #4, it seems like a good idea but, like you, I don't know what will break. So maybe it's something to note for the future.

    Quote Originally Posted by Jacob.Schultz View Post
    I helped someone with a project yesterday and had a look at TeensyThreads and found some flaws in it. I hope this can help.

    1. The way FPU registers are saved and restored unconditionally are very inefficient. Cortex uses lazy stacking and all you have to do is: (google it for technical info)

    // save
    tst r14, #0x10
    it eq
    vstmdbeq r0!, {s16-s31}

    // restore
    tst r14, #0x10
    it eq
    vldmiaeq r0!, {s16-s31}

    2. The threads_svcall_isr interrupt should have the lowest priority (0xff) on the system. Or it’s impossible to yield from any interrupt with lower or same priority.

    3. The use of noinline attributes makes no sens. An advice: Always develop and test you code the optimizer on full throttle -O3 (don’t use lto as default). You can always turn it off if you want to debug. It’s always easier discover and correct the errors right away and the optimizer is normally not destroying anything if done correctly. (Be carefull, the Internet is floating with a lot of corrupt examples on inline asm)

    4. Interrupts are disabled longer than necessary, it is recommended to use BASEPRI instead of disabling all interrupts. But that change is up to PJRC or it will break compatibility. Freertos has done a decent job, look at a small file under Source/portable/GCC/ARM_CM4F/port.c

  7. #382
    Junior Member
    Join Date
    Feb 2017
    Posts
    4

    Lightbulb

    Hi,

    first of all thank you for this great library….I just want to be sure that i understood the threading right…

    I coded:
    Code:
    threads.setSliceMicros(100);
    const int instrumentUpdateThread = threads.addThread(updataInstValuesThreadFunction);
    threads.setTimeSlice(threads.id(), 5);// This is the main loop as thread
    threads.setTimeSlice(instrumentUpdateThread, 10);// This is an additional thread
    …..
    
    void loop()
    {
    …..do things here (costs approx. 400 µsec)
    threads.delay(20);    // Will give 20 msec to other threads ?
    }
    
    void updataInstValuesThreadFunction()
    {
         int i = 0;
        do
        {
          i++;
        }while(true);
    }
    OK as far as i understood the threads…
    Setting "setSliceMicros" to 100 => means 100 ticks is one time slice
    Setting "setTimeSlice(…) to 5 => means 5 * 100 = 500 ticks will be the main loop running without context task switch ?
    => so if approx 1 tick is 1 µsec => the "do things here" will not be interrupted ?
    => then threads.delay(20) will switch to "updataInstValuesThreadFunction" which has now time to do things for 20 ms=>20000 µsec and will be called multible times then ?
    Which effect does it have to rise the number of ticks avail for one thread ? Higher priority and/or less context switches ?

    Thank you very much for your help

    Torsten

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •