リンカースクリプトを更新、そして元に戻す

やらかした・・・

良かれと思って行った修正が、実は、良く無かった事は良くある事とはいえ、今回は久しぶりにやらかした・・・

リンカースクリプトを更新

以前のリンカースクリプトは、gcc-6.4.0 位の物で、現在メインに利用している gcc-8.3.0 の物より若干古い。
そこで、8.3.0 ベースの物に全て更新した。

独自の記述もあるので、多少切り貼りをしているものの、基本は同じものと思う。


RAYTRACER_sample を動かして気がついた・・・

リンカースクリプトを更新して、全てでは無いものの、いくつかのソフトを動かして、まぁちゃんと動いているなぁーと確認して、全てコミットした。
全 RX マイコンのリンカースクリプトなので、それなりのファイル数となっている。

ところが、「RAYTRACER_sample」で奇妙な動作をしている事に気がついた。

    bool        run_ = false;
    int         sampling_ = 1;
    int         render_width_  = 320;
    int         render_height_ = 240;

このコードは、main.cpp 無地の namespace でくくられている部分で、起動時に、ROM 領域から、コピーされる。

ところが、renderheight が、「0」になっていて、起動時にこのパラメータでレンダリングするのだが、それが原因で奇妙な動作になる・・・

初期値が正しくコピーされていない。

以前は、正しく動いていたと思えるので、どうやら、リンカースクリプトが怪しい事と思い、以前のリンカースクリプトに戻してみた。
すると、この問題が解消された。

うーーん、これはヤバイなぁーと、リンカースクリプトの更新時のすり合わせを行った。

異なる部分

gcc-8.3.0 の rx.ld では、C++ のインスタンスを初期化するルーチンのリスト「ctor」は ROM 領域にのみ配置されている。

 .init :
  {
   KEEP (*(.init))
   __preinit_array_start = .;
   KEEP (*(.preinit_array))
   __preinit_array_end = .;
   __init_array_start = (. + 3) & ~ 3;
   KEEP (*(.init_array))
   KEEP (*(SORT(.init_array.*)))
   __init_array_end = .;
   __fini_array_start = .;
   KEEP (*(.fini_array))
   KEEP (*(SORT(.fini_array.*)))
   __fini_array_end = .;
   } > ROM

一方、gcc-6.4.0 では、data 領域に配置されており、起動時に、ROM 領域から RAM にコピーされて利用される。

  .data : {
    . = ALIGN(4);
    PROVIDE (__datastart = .); /* IF_ROROM */
    PROVIDE (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE (__preinit_array_end = .);
    PROVIDE (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array))
    PROVIDE (__init_array_end = .);
    PROVIDE (__fini_array_start = .);
    KEEP (*(.fini_array))
    KEEP (*(SORT(.fini_array.*)))
    PROVIDE (__fini_array_end = .);
    LONG(0); /* Sentinel.  */

...

    . = ALIGN(4);
    _edata = .;
    PROVIDE (edata = .);
    PROVIDE (__dataend = .);
  } > RAM AT> ROM

この関数リストは、起動時、わざわざ RAM にコピーするのは無駄なので、ROM 領域だけに配置する事は、メモリを節約する意味もあり、意味があると思える。
ただ、これを元に戻すと、正しく動作しなくなる・・・

不思議なのだが、gcc-8.3.0 だと、data 領域は 2168 バイトとなっている。

rx-elf-size raytracer_sample.elf
   text    data     bss     dec     hex filename
  51244    2168    8120   61532    f05c raytracer_sample.elf

ところが、gcc-6.4.0 だと、data 領域は 48 バイトと少なくなっている

rx-elf-size raytracer_sample.elf
   text    data     bss     dec     hex filename
  53364      48    8120   61532    f05c raytracer_sample.elf

text 領域の 2120 バイト分が data 領域に移動している?

何故、こうなるのか、さっぱり判らない・・・

結局、元に戻すしか無いのかもしれないが、直すファイル数がとてつもなく多い・・・うーーーん・・・
しかし、原因が判らないので、とりあえず、元に戻してコミットしなおした。


FPU の無い RX220 で RAYTRACER_sample を走らせたら、劇遅かったw

RX220 でも走らせた、最初、何か止まるなぁー、何が悪いの?
と、色々調べたらー、単に遅いだけだったw

# render
Render time: 291320ms (1)

「291秒」・・・
48MHz の RX140 では 1.8 秒なのを考えると、劇遅・・・
動作周波数が 32MHz と少し遅い事もあるけど、FPU が無いと 100 倍以上遅い、こんだけハンディになるのかー、まぁ、それはそうだけど、これは厳しいよなぁー・・・

やっぱ、FPU が無いマイコンは使う価値が薄いとつくづく実感するー

RX マイコンの場合、FPU の有る無しで、コストがそんなに変わらない場合もあり、浮動小数点を扱わないアプリなら別だけど、逆説的に、FPU を搭載していない RX マイコンを選択する理由が無いように思える。