RX65N Envision Kit が発売されてもうじき1年がたとうとしているが、アプリケーションを作っている人は非常に少ないように感じる・・
サーチエンジンで探しても、あまり有益な情報を探せない、現在、秋月では売り切れとなっており、それなりに購入している人はいると思うのだが、何か面白いアプリを作って発表し、ソースコードを公開している人はほとんどいないように感じる。
何がハードルになっているのか?・・・
それに比べて、M5Stack、ESP32、ARMなど海外のマイクロコントローラーは、非常に沢山あるようなのだが・・・
※何かあったら、リンクを教えて下さい。
さて、以前に「Arduino 用レイトレーサー」を実装している人がいて、コードが公開されていたので、RX65Nにポートしてみた。
その過程で、ルネサス公式のフォーラムにそのリンクを張った。
しばらくして、色々な指摘を受けた。
※自分のブログにも同じような指摘が返信されていたが、検証の材料が無く、ほぼスルー状態だった。
※自分の間違った知見もある・・
ルネサスのフォーラムでは、具体的な実験を行い、検証を行ってくれた。(感謝)
※単に思いつきで返信するだけじゃなく、このような、有益な内容のある濃い情報が重要だ、言うだけなら誰でもできる、何か発信するなら、せめて、自分で「手」を動かして、検証可能な情報を返して欲しいものだ。
そこで、指摘された事についてまとめておきたい。
- gcc では RXv2 コアの最適化が不十分
- double 定数を使っているのが余計
- std::sqrt はdoubleの関数なので、sqrtf を使った方が良い
- RXv2には、fsqrt 専用命令が用意されている
- ESP32 などで公開されているベンチマークは、レイのサンプリングは「1」で行っているがRXでは、「4」で行っていて条件が異なる
gcc の RXv2 の最適化に関しては、自分の考え方が少しある。
まず、gcc のオフィシャルなソースコードを使う事を前提としているので、ルネサス社が、gcc に最適化のコードをコミットするまで待つしかない・・
現在ルネサス社は、独自にGNUツールを公開しているが、最新版は4.8系となっており、C++ の最新のコードをコンパイルする事が出来ない。
※ルネサス社が提供するGNUツールでコンパイルした場合、最適化「-O3」で、最大7~15%くらい良いコードが出る場合があるようだが、これは今後検証してみたい。
※オフィシャルな gcc では、「-mcpu=rx64m」など専用デバイスのオプションは無いが、標準で、RX600 系のコード出力となっている。
double の定数や、double 専用 API は、指摘を受ける前に既に、変更済みで、それで、ほんの少し高速になっていた。
標準の数学ライブラリでは、平方根を求める「sqrt、sqrtf」はニュートン法を使っており、RXv2 に備わっている、fsqrt 専用命令とは微妙に計算結果が異なっているものと思うので、標準では使わないのだと思っていた。
だが、この命令に切り替えた場合、倍の速度でレンダリングするようなので、この知見を素直に受け入れた。
#if defined(SIG_RX64M) || defined(SIG_RX71M) || defined(SIG_RX65N) || defined(SIG_RX24T)
static inline float sqrtf_(float x)
{
__asm __volatile(
"fsqrt %0, %0\n" \
: "+r"(x) \
);
return x;
}
static inline int ceilf_(float x)
{
int y;
__asm __volatile(
"pushc fpsw\n"
"mvtc #0b10, fpsw\n"
"round %0, %0\n"
"popc fpsw\n"
: "=r"(y) \
: "r"(x) \
);
return y;
}
#else
static inline float sqrtf_(float x) { return sqrtf(x); }
static inline int ceilf_(float x) { return ceilf(x); }
#endif
レイのサンプリング数に関しては、全くノーマークだった、元ソースでは、標準「4」だったので、素直に「4」で行っていたが、ベンチマークを行っている Arduino のスケッチでは、「1」にして API を呼んでおり(卑怯なのではw)、大体4倍のレンダリング時間となっていた。
※「STM32F7 200MHz」では、0.62秒と非常に高速なので、この違いは、何なのか、疑問に思っていた・・・
以上の知見を受け、RX65N Envision Kit でレンダリングすると・・・
約0.83秒と、STM32F7 200MHz と比較しても、十分戦闘力のある値となったw
元は7.7秒とかだったので、素晴らしいパフォーマンスアップとなった。
※ESP32(160MHz)は、13秒みたいだが、これは、他にバリアとなる事象があるように思う
※このような有益な情報を提供してくれた「fujita nozomu」氏に感謝したい!
全ソースコードは以前から公開しているが、コンパイル環境を作り、フレームワークなどをチェックアウトする必要があるので、実行バイナリーも公開している。
・裏にあるスイッチを押す毎に、フルスクリーン(480×272)、レイのサンプリングを変更してのレンダリングを行う。
「raytracer.hpp」は、かなり柔軟性があり、ベンチマークには最適なので、PIC32や、他のマイコンでも十分実行できる、別のマイコンで試した人がいれば、是非情報を公開して欲しい~