FPGA開発日記

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

自作Binary Translation型RISC-Vエミュレータの性能解析

自作RISC-Vエミュレータの性能解析続き。私はWSL1を使用しているので、Rustの性能解析ツールflamegraphを使用することができない(どうもLinuxのツールが必要で、これがWSL1では使用できないようだ)。

qiita.com

AWS上に急遽Rustの環境を構築し、そこでflamegraphによる性能解析を行った。Dhrystoneを実行し、flamegraphによる性能解析を実行した。

$ cargo flamegraph --bin dydra -- --machine sifive_u --elf-file /home/msyksphinz/work/riscv/freedom-e-sdk/software/dhrystone/release/dhrystone.elf

これ取得したflamegraphが以下である。...なんかHashMapの処理がほとんどだな...RustのHashMapが遅いと聞いていたが、これは処理のほとんどがHashMapではないか。

f:id:msyksphinz:20201201012952p:plain

HashMapがなぜこんなに遅いのだろう、ということでいろいろ調べていたのだが、以下のようなそのまんまなQ&Aを発見した。

prev.rust-lang.org

代替手段としてはFnvHashMapというのがあるらしい。じゃあとりあえずこれを使えば高速になるのかな?

https://crates.io/crates/fnv

現在の実装をFnvHashMapを使って置き換えてみた。

diff --git a/src/emu_env.rs b/src/emu_env.rs
index 163a554..7525eeb 100644
--- a/src/emu_env.rs
+++ b/src/emu_env.rs
@@ -2,7 +2,7 @@ use std::cell::RefCell;
 use std::rc::Rc;

 use mmap::{MapOption, MemoryMap};
-use std::collections::HashMap;
+use fnv::FnvHashMap;
 use std::mem;

 use crate::elf_loader::{ELFLoader};
@@ -68,7 +68,7 @@ pub struct EmuEnv {
     pub m_prologue_epilogue_mem: MemoryMap,
     pub m_guest_mem: MemoryMap,

-    pub m_tb_text_hashmap: HashMap<u64, (usize, Rc<RefCell<MemoryMap>>)>,
+    pub m_tb_text_hashmap: FnvHashMap<u64, (usize, Rc<RefCell<MemoryMap>>)>,
     pub m_curr_tb_text_mem: Rc<RefCell<MemoryMap>>,

     pub m_host_prologue: [u8; 15],
@@ -167,7 +167,7 @@ impl EmuEnv {
                 Ok(m) => m,
                 Err(e) => panic!("Error: {}", e),
             },
-            m_tb_text_hashmap: HashMap::new(),
+            m_tb_text_hashmap: FnvHashMap::default(),
             m_curr_tb_text_mem: match MemoryMap::new(1, &[]) {
                 Ok(m) => Rc::new(RefCell::new(m)),
                 Err(e) => panic!("Error: {}", e),

これで同じようにベンチマークを実行してみた。

Simulator Dhyrstone Time[s]
QEMU-5.1.0 0.789
Dydra-a78da94 FnvHashMap使用 3.7488
Dydra-6ec3e02 初期版 5.4504
Spike 28.909

うーん、ちょっとだけ速くなった気がする。同じようにflamegraphを取得してみた。

f:id:msyksphinz:20201201013027p:plain

どっちにしろHashMapが支配的なのは変わっていないよ?もうこれはHashMap自体の使用をやめるべきか。HashMapを使っている部分は変換後TCGを記憶しておくところで、一度登録したTCGをつ年キイ臆しておく必要はなく、キャッシュのように消えても構わないので、普通の配列のようなキャッシュ構成を使うべきなのか?