ラベル ARM の投稿を表示しています。 すべての投稿を表示
ラベル ARM の投稿を表示しています。 すべての投稿を表示

2020年8月3日月曜日

arm gccが改めてすごいと感じたこと

サイクルカウンタを使ってみて気になったのはパフォーマンスカウンタを有効にしていると発熱や消費電力に影響があるのかないのか?気にはなりますが、おそらく数字に出てこないレベルなのではないかと思うのですが、とはいえ、使用が終わったらカウンタを止めておきたいと思ったときに、本当に止まっているのかテストをしてたところ、

    while((cnt<50000) && (((unsigned long)end - start)<150)){
        cnt++;
        end = pmon_read_cycle_counter();
    }
    if(isStart){
        pmon_stop_cycle_counter();
        dummy = pmon_read_cycle_counter();
        printf("stop\n");
        dummy2 = pmon_read_cycle_counter();

        printf("%ld, %ld\n", dummy, dummy2);
    }

まぁこんなことをやってみたわけです。
サイクルカウンタのテストプログラムでも、一定の回数を回している上記のループが終わった時のカウンタの値が150なのでたまたまかな?と思っていたんですが、これが上記の物でも150という数字を返してきました。
何がすごいかといえば、ループの終了条件判断の分岐とその後の条件文の分岐を無視して機械語レベルで1サイクルの中でサイクルカウンタが止められているということです。
armの特性として、実行条件が命令と結合しているので条件分岐がハマれば実行順序の乱れが無いというのは分っていたのですが、ここまで正確に数字に出てくると驚きの方が大きかったです。
試しに停止直前に
        dummy = pmon_read_cycle_counter();
        pmon_stop_cycle_counter();
        dummy = pmon_read_cycle_counter();
などと、やってみましたが、これで返される値は151という。
dummyに代入するところは直後に再度同じdummyに代入しているので、最適化で外されているとは思いますが、インラインアセンブラとは言え本当に1cycleしかかかっていないとか…

正直凄い以外の言葉が出ない。

2020年8月2日日曜日

ARMのサイクルカウンタ

先の投稿でARMなにがしの手順はあったのですが、結局Raspberry piで使えるのかどうか確認するのにえらい手間取りました。
そもそもARMでの開発をするためのバイブルなんて一切ないので。
昔は書店に行って「やっぱりない」と言うことがとても多く、無駄なお金を使っていましたが、今ならアマゾンとかあるので、、、
だからポチるのか?と言われれば、まずは下調べからしないと痛い目を見そうですし、そもそもARMの種類ってよくわかんないんですよねw気づけば64bitだとか。
とりあえずダイレクトで検索して見るとバイブルっぽいPDFがいくつかありました。
さらに、Raspberry pi 2bで採用されているARMv7の仕様書っぽい感じのものがありました。
https://static.docs.arm.com/ddi0406/c/DDI0406C_C_arm_architecture_reference_manual.pdf
英語なので細かい所はさっぱりですが、コードとその場のノリでなんとなく必要なことが見えてきました。
少なくてもRaspberry pi 2bなら ARM Coretex-A9と同じ手順で行けそうな気配がしてきました。
Raspberry pi 3bとかはARM Coretex-A53とかA72とか互換性はどんな風になってるのか想像できません…下位互換性なCPUでも結構維持されていなかったりするのであれなんですが、そもそもの拡張のされ方とか内容と型番を覚えるのが苦手なので正直つらいですw

パフォーマンスカウンタが複数設定できそうなところとかが良くわかってませんが、一つ一つ確認したところポイントは変わっていないのが確認できました。
まぁ最悪カーネルパニックになるだけなので、とっとと試したいと思います。


ソースファイルなどを準備して、まずは…権限付与ドライバからいきましょうかね。
pi@rasp4b4g:~/pmon $ ls
Makefile  pmon_ca9.h  pmuser.c  test.c
pi@rasp4b4g:~/pmon $ make
make -C /lib/modules/5.4.51-v7l+/build M=/home/pi/pmon modules
make[1]: ディレクトリ '/usr/src/linux-headers-5.4.51-v7l+' に入ります
  CC [M]  /home/pi/pmon/pmuser.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC [M]  /home/pi/pmon/pmuser.mod.o
  LD [M]  /home/pi/pmon/pmuser.ko
make[1]: ディレクトリ '/usr/src/linux-headers-5.4.51-v7l+' から出ます
pi@rasp4b4g:~/pmon $ ls
Makefile        modules.order  pmuser.c   pmuser.mod    pmuser.mod.o  test.c
Module.symvers  pmon_ca9.h     pmuser.ko  pmuser.mod.c  pmuser.o
ドライバが作れる環境なのと、すこしmakeを調べたので手直しすべき部分はあっさりとクリアw
さて…
pi@rasp4b4g:~/pmon $ gcc -o test test.c
pi@rasp4b4g:~/pmon $ ./test
Illegal instruction
権限がないと、例外が発生するのも確認。
pi@rasp4b4g:~/pmon $ sudo insmod ./pmuser.ko
pi@rasp4b4g:~/pmon $ ./test
time = 94, x = 500500
pi@rasp4b4g:~/pmon $ ./test
time = 105, x = 500500
pi@rasp4b4g:~/pmon $ ./test
time = 94, x = 500500
無事動作確認が取れました!
ARM Cortex-A72の4bで行けたから2b以降なら大丈夫でしょう(ただし32bit環境)…ということで。

これで…150サイクルが実現できて、ドライバ内で処理が完結しやすくなります。
pi@rasp4b4g:~/pmon $ sudo rmmod pmuser
で削除するか再起動をお忘れなく…

サイクルカウントのヒント?

全然関係のないことを調べていたら検索結果にタイムリーな記事が。
サイクルカウントできそうな話題!
正直なところ、モード切替の150サイクルを待機する部分がお手上げだったのでソースを探して…まではしたんですけど、いままでまったく興味が無かった部分でソースや断片がどこにあるのかとか明るくないのでそちらもお手上げでしたw
で、いきなり「コプロセッサとアクセス…」ドライバ側で何もしないでアクセスできるのかどうか不安になりつつも、少し見ていくとそれの元ネタのページへのリンク。
なんとなく行けそうなタイトルです。「このソースは特権モードで使用することを想定しています。」ど、ドライバ内で使えるのかな?

早速組み込んで遊んでみようかな。

見てみると色々と捉え方が変わりますね。まずドライバをinsmodすると初期化処理が動いてrmmodするまでそのままの状態であるということ。確かにそうですが、こんな感じに利用するのが本来の使い方なのかな?。確かに権限付与とかやりやすそうな実装に見えます。