Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

キャッシュエミュレーションの実装 #1

Closed
tkojima0107 opened this issue Jul 19, 2019 · 12 comments
Closed

キャッシュエミュレーションの実装 #1

tkojima0107 opened this issue Jul 19, 2019 · 12 comments
Labels
enhancement New feature or request

Comments

@tkojima0107
Copy link
Collaborator

オリジナルの実装ではキャッシュらしきものはあるがdirect mapでしかも、ブロックサイズ=1のキャッシュと呼んで良いのかわからない代物。加えてライトスルー方式。

キャッシュミスペナルティも考慮したn-way associative cache化したい。

順番としては

  1. キャッシュとしての振る舞いをエミュレーション
  2. キャッシュミス時のstallを実装
    という手順で進めていく。

ただし、キャッシュミス時のstallを実装するには少なくとも以下を考慮する必要がある。

  • 5ステージパイプラインでは命令キャッシュとデータキャッシュでミスするステージが異なる
    • 命令キャッシュはFetchスレージ
    • データキャッシュはMEMスレージ
    • 当然同時にミスすることも考慮しなくてはいけない
  • 遅延スロットの取り扱い
    • VMIPSでは厳密にパイプラインをエミュレーションできてない
      • 多くはEXEステージを毎サイクル実行?

あとMIPS R3000ってデータハザードでパイプラインの停止とかインターロックって実装されてたのか忘れたから調べる

@tkojima0107 tkojima0107 added the enhancement New feature or request label Jul 19, 2019
@tkojima0107
Copy link
Collaborator Author

#2 を実装することを考えるとキャッシュミス時に サイクル時間 += ペナルティ とするのではダメ
理由は以下の2つ

  • キャッシュミスによるストール時にもアクセラレータは動いていなくてはいけない
  • キャッシュフェッチするデータがTCIを経由したアクセラレータ内データの場合がある(TCIをちゃんとエミュレーションするならこのフェッチにかかる時間は予測不可)

@tkojima0107
Copy link
Collaborator Author

16760a5 でn-way キャッシュの動作エミュレーションはできた。あとは、サイクル数をエミュレートする

@zoubleton
Copy link
Collaborator

Image from iOS

@tkojima0107
Copy link
Collaborator Author

8dfecc1 にてキャッシュをmapperから分離できた。
また、もともとあるDeviceExcクラスがCPUの親クラスだったので、これに

void stall(int cause);

をプロトタイプとして組み込んでみた。実際に使うとなるとこれではダメなきがするから拡張する可能性あり。

@tkojima0107
Copy link
Collaborator Author

tkojima0107 commented Aug 27, 2019

やること

  • Cache::stepの実装(cache fetch/cache write back)
  • mapper::readyを使ってstallをエミュレーション
  • @zoubleton
    • mapperにアービトレーション
      • Mapper::ready()で相手に通知する (rangeインスタンスのreadyも考慮)
      • アクセスの初期遅延をMapper::step()で制御
        到達遅延はmapperで制御、計算による遅延はrouterで制御
    • DMACの実装

@tkojima0107
Copy link
Collaborator Author

stallなしでjpegした場合の結果

2757827 instructions in 0.58308 seconds (4729798.053 instructions per second) (stall ratio 1.031%) 
Instruction Cache Profile 
	Cache Miss Ratio 0.04891% 
	write back ratio 0.00000% 
Data Cache Profile 
	Cache Miss Ratio 6.48642% 
	write back ratio 34.27902% 

@tkojima0107
Copy link
Collaborator Author

やること再確認

メモリアクセスのインターフェース

  1. Bool ready(uint32 addr, int32 mode, DeviceExc *client);
    counterが0かつrange側のreadyがたったらtrueを返す
  2. void requstWord(uint32 addr, int32 mode, DeviceExc *client);
    mapperにエントリがない場合counterを初期化、それ以外は無視 -> cpu,cache側からいくら読んでも良い
  3. uint32 fetch_word(uint32 addr, int32 mode, DeviceExc *client);
    mapperのエントリを削除する
    fetch_halfやstore_wordなども同様

前提

  • cpuとキャッシュから同時にrequestが来ないようにする
  • キャッシュのバーストアクセスを再現するには初めに全ライン分requestを飛ばし、一斉にcounterをdecrementしてもらう

@tkojima0107
Copy link
Collaborator Author

キャッシュミスを考慮した結果

3751539 instructions in 0.53646 seconds (6993151.387 instructions per second) (stall ratio 27.246%)
Instruction Cache Profile
	Access Count 2730713
	Cache Miss Ratio 0.04889%
	write back ratio 0.00000%
Data Cache Profile
	Access Count 742993
	Cache Miss Ratio 6.09131%
	write back ratio 34.27902%

所用サイクル数が1.36倍になった。
フェッチミスの場合余分に15サイクル
データミスでライトバックありの場合31サイクル, それ以外は15サイクル余分にかかるから
フェッチのペナルティ: 2730713 * 0.00048 * 15 = 1,311
データアクセスのペナルティ: 742993 * 0.0609 * ((1 - 0.342) * 15 + 0.342 * 31) = 926,322
(2757827 + 1311 + 926322) / 2757827 = 1.33
妥当そう

@tkojima0107
Copy link
Collaborator Author

tkojima0107 commented Nov 8, 2019

ちなみにGeyser RTLシミュレーションでは

236725700: end successfully
Simulation complete via $finish(1) at time 236925700 NS + 0
../forTest/testamode.v:166          $finish;
ncsim> exit

real    1m14.382s
user    1m3.892s
sys     0m0.115s

1 cycle = 50nsなので4,734,514サイクル
オーダーは悪くない

シミュレーションにかかる時間は150倍くらい

@tkojima0107
Copy link
Collaborator Author

ひとまずできたが遅い

 %   cumulative   self              self     total           
 time   seconds   seconds    calls  us/call  us/call  name    
 99.14     87.89    87.89  3993040    22.01    22.01  Mapper::step()
  0.08     87.96     0.07  3993040     0.02     0.02  CPU::pre_decode(bool&)
  0.07     88.02     0.06  8041079     0.01     0.01  Cache::cache_hit()
  0.07     88.08     0.06  5981261     0.01     0.02  std::_Hashtable<Mapper::RequestsKey, std::pair<Mapper::RequestsKey const, int>, std::allocator<std
::pair<Mapper::RequestsKey const, int> >, std::__detail::_Select1st, Mapper::RequestsKeyEqual, Mapper::RequestsHash, std::__detail::_Mod_range_hashing, 
std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::find(Mapper::RequestsKe
y const&)
  0.06     88.13     0.05  9461440     0.01     0.01  std::_Hashtable<Mapper::RequestsKey, std::pair<Mapper::RequestsKey const, int>, std::allocator<std
::pair<Mapper::RequestsKey const, int> >, std::__detail::_Select1st, Mapper::RequestsKeyEqual, Mapper::RequestsHash, std::__detail::_Mod_range_hashing, 
std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_find_before_node(uns
igned long, Mapper::RequestsKey const&, unsigned long) const
  0.06     88.18     0.05  1502077     0.03     0.03  Options::optstruct(char const*, bool)
  0.05     88.22     0.05  3993040     0.01    22.20  vmips::step()
  0.05     88.26     0.04  2757869     0.01     0.03  CPU::fetch(bool&, bool)
  0.03     88.29     0.03  3993040     0.01     0.01  CPU::pre_mem_access(bool&)
  0.03     88.32     0.03  2729387     0.01     0.01  CPU::decode()

@tkojima0107
Copy link
Collaborator Author

アービタの話題は #7

@zoubleton
Copy link
Collaborator

zoubleton commented Nov 8, 2019

3d22720: すべてのカウントをデクリメントするのではなく、最初のリクエスト時でのサイクル数を保持し、現在のサイクル数との差からreadyを算出するように仕様変更
a7651cf: store_wordでreadyの時リクエスト時のサイクル数を削除するように修正
1b55c04: 上に加え、readyでないときにbus_errorを起こすコミット
b14edc7: stall_emuをmerge

以下は b14edc7 を手元のMacBook Pro(Early 2015)で実行した時のシミュレーション時間

./cube_sim test_vec/jpeg.bin  0.72s user 0.01s system 98% cpu 0.740 total

速くなった。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants