FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

バイナリのロードがすごく遅いので何が起きているのか調査(解析編)

xv6のバイナリをISSで実行しているが、最初のバイナリのロードでもの凄く時間がかかっている。 ロードだけで1分くらいはかかっているように感じる。

github.com

github.com

まずは、Google Perftoolsを使って、何が発生しているのかを調査した。 Google Perftoolsはもうシミュレータのバイナリに組込めるようにcmakeを作っているので、オプションを変えてビルドするだけだ。

cmake -DUSE_GPERF .
make

できた。これで、実行するだけで性能解析を行ってくれる。

CPUPROFILE=/tmp/swimmer.prof ~/swimmer_riscv/build_mips/swimmer_mips --binfile kernel --debug --out debug.log --debug_func --debug_gvar  --init_pc 0x80100000
pprof ~/swimmer_riscv/build_mips/swimmer_mips /tmp/swimmer.prof

これで、解析そのものはできる。まずはtopからだ。

$ pprof ~/swimmer_riscv/build_mips/swimmer_mips /tmp/swimmer.prof
Using local file /home/vagrant/swimmer_riscv/build_mips/swimmer_mips.
Using local file /tmp/swimmer.prof.
Welcome to pprof!  For help, type 'help'.

(pprof) top
Total: 7356 samples
    1285  17.5%  17.5%     6277  85.3% Memory::InsertMemTable
    1100  15.0%  32.4%     1311  17.8% __gnu_cxx::__normal_iterator::operator++
    1054  14.3%  46.8%     1325  18.0% __gnu_cxx::operator!=
     831  11.3%  58.0%      831  11.3% __gnu_cxx::__normal_iterator::__normal_iterator
     813  11.1%  69.1%     1259  17.1% std::vector::end
     671   9.1%  78.2%      671   9.1% MemoryBlock::GetBaseAddr
     631   8.6%  86.8%      631   8.6% MemoryBlock::GetBlockSize
     436   5.9%  92.7%      436   5.9% __gnu_cxx::__normal_iterator::base
     431   5.9%  98.6%      431   5.9% __gnu_cxx::__normal_iterator::operator*
      26   0.4%  98.9%      124   1.7% Memory::SearchMemTable

あー、やっぱり、バイナリをメモリに格納するところで時間がかかっている。特にInsertMemTableは、ベクタを探索して、適切なブロック見つけ出し、発見できなければ新しいブロックを探索するというようになっているので、最初のバイナリが非常に大きければ、それだけ時間がかかる。 これは、もうちょっと別の方法で削減できないかなあ。