📷️

Spresense でマルチスレッド

に公開

Spresense でマルチスレッド

はい、今日も Spresense いじってます。記録残すのも後1,2回で終わりたい。

Spresense は SMP/ASMP 両方に対応していますが、明示的に機能を有効化しなければ使うことが出来ません。 pthread を作成しても SMP が有効でなければ単一コアでスケジューリングされるようです。

というわけで、 SMP を試した記録です。

まとめ

spr-config default feature/smp +SMP_NCPUS=

上記で SMP に割り当てるコア数を変えられます。

以上です、お疲れ様でした。

作ったもの

https://github.com/nodamushi/zenn-program/tree/main/src/spresense/multi_thread

プログラムの説明

  • Thread1
    • Thread1 用の volatile int の値をひたすら足し算
    • 優先順位 (110)
  • Thread2
    • Thread1 と Thread3 の計算結果を表示(printf)
    • 優先順位 (105)
  • Thread3
    • Thread3 用の volatile int の値をひたすら足し算
    • 優先順位 (100)

Thread1, Thread3 の内容はただただ足し算してるだけでコンテキストスイッチする間がないので、自分より低優先順位のスレッドは動かないはずです。

Thread2 は printf してるので、もしかしたら IO 操作で wait かかって低優先順位のスレッドが動くかも?ぐらいの予想ですね。

https://github.com/nodamushi/zenn-program/blob/main/src/spresense/multi_thread/src/thd/thd_main.c

SMP 無効の場合

SMPを無効(デフォルト状態)のままビルドした場合:

spr-config default
spr-make -j

このような結果になります。

NuttShell (NSH) NuttX-12.3.0
nsh> thd
Start Threads
[Thread2] Thread1=100000, Thread3=0
[Thread2] Thread1=100000, Thread3=0

~略~

[Thread2] Thread1=100000, Thread3=0
[Thread2] Thread1=100000, Thread3=0
Thread 2 Done
Done

Thread1 の値が全部 100000 で、 Thread3 が全部 0 なので、 Thread2 は Thread1 が終了後に占有して実行され、その後 Thread3 が動くという挙動ですね。 printf でコンテキストスイッチは起こらないようです。

SMP 有効の場合

SMPを有効でビルドした場合:

spr-config default feature/smp
spr-make -j

feature/smp を取り込むと、2コア分が SMP に使われるようです。となると、先の結果から考えるに、Thread1とThread2 が同時に走り、最後に Thread3 が走るはずです。

NuttShell (NSH) NuttX-12.3.0
nsh> thd
Start Threads
[Thread2] Thread1=2740, Thread3=0
[Thread2] Thread1=6728, Thread3=0
~略~
[Thread2] Thread1=98421, Thread3=0
[Thread2] Thread1=100000, Thread3=0
Thread 2 Done
Don

Thread1 の値が変化しつつも、 Thread3 が全部 0 なので、 Thread2 は Thread1 は同時に実行され、その後 Thread3 が動くという挙動ですね。予想通りです。

SMP のコア数を3にした場合

最後に、 SMP に割り当てるコア数を 3 にしてみましょう

spr-config default feature/smp +SMP_NCPUS=3
spr-make -j

今度こそ、全てのスレッドが同時に動くはずです。

NuttShell (NSH) NuttX-12.3.0
nsh> thd
Start Threads
[Thread2] Thread1=2878, Thread3=0
[Thread2] Thread1=7034, Thread3=33
[Thread2] Thread1=10697, Thread3=3723
~略~
[Thread2] Thread1=94876, Thread3=88516
[Thread2] Thread1=98891, Thread3=92562
[Thread2] Thread1=100000, Thread3=97020
[Thread2] Thread1=100000, Thread3=100000
~略~

予想通り、 Thread1, Thread3 の値が同時に変化しているので、全てのスレッドが同時に動作していることが確認できます。

以上

Discussion