トップ «前の日記(2007-07-26) 最新 次の日記(2007-07-28)» 編集

U-memo

2006|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|08|
2009|08|10|
2010|02|03|
2011|11|12|
2012|04|
2016|02|
All= / Today= / Yesterday=

2007-07-27

_ [プロセッサ] キャッシュの真実

たるさんの新作 に対するツッコミ。

データ量が小さいPC用途では キャッシュの恩恵は絶大である。一度BIOSでキャッシュを切ってマシンを動かしてみればその効力が如何に大きいかは実感していただけると思う。

Intel さんの中身を解析しているわけじゃないので憶測でしかないですが、 Cache off 設定の場合には、単にキャッシュが無い設計よりもかなり 遅くなると思われます。 すでにキャッシュがある前提の設計をしているうえに、 そもそも通常使われることが無い cache off 設定は「矛盾なく動く」 程度に簡素化されているはずですから。

特に、write-back cache の作りに対する cache off 動作ってのは (ストア動作が)もともと相性が悪すぎるので、 互換性のために残しているに過ぎない設定をもって判断するのは危険です。

# 下手すると、1命令実行ごとにキャッシュフラッシュして見かけをごまかしてるだけかもしれませんよ :-)

まぁ、x86 はメモリオペレーションが多い(RISCに比べてね)命令セット なので、キャッシュがないことによる痛手がかなり大きいのは事実ですが。

次に、PentiumM発表時に使われた公開資料を見てみよう。この資料によると、CPUの動作時間の内データミスで約20%のマシンタイムが奪われている。

--> http://www.watch.impress.co.jp/pc/docs/2002/0919/kaigai01.htm

この図の割合が何に対する割合かがわからないのが罠なのですが、 少なくとも「ストールしていない」は必ずしも最高の ILP 性能が でているわけではないです。 μarch 上は4並列実行できるはずなのに1並列(!?)実行で あってもストールはしていないので「実行」扱いでしょう。

20% は「本当に何もやることが無い時間」として計上されているとみなす方が 無難で、実行の53%の中にもキャッシュストール要因が含まれている 可能性が高いです。 で終わると根拠が薄弱なので別の資料を見てみます。

安藤さんの報告 による SPARC64 V の動作グラフを同じように読み取ると、

  • メモリストール ($,System) 35% くらい?
  • コアストール (分岐予測?) 20% くらい?
  • 実行 45%くらい?

になっている。 PentiumM よりもメモリストールが大きいけれど、 比較する分にはそんなに変な数字ではないでしょう。

このグラフでは、ストールしなかった部分について 1〜4 並列に 分類されているところに注目すべし。 4命令並列commitになっているのは10%もない。 じゃあ、1〜3並列(あるいは0の一部も含まれるだろう)はなぜ?という疑問がわくのだが、図はそれには答えていない。

その理由は謎、ということで。

# まぁ、100% hit のキャッシュがあっても2倍に性能があがる可能性はほとんどないですが。

ここで、この性能向上の予想に役立ちそうな情報がある。それは以前AMD64系で2次キャッシュ容量が2倍になったCPUとクロックを10%向上した CPUは同じ性能のプロセッサナンバーとして扱われていたという点だ。つまり、2次キャッシュ容量が2倍になると、性能はクロック10%分向上する事になる。

現実にはありえない「キャッシュ100%ヒット」を考えるとき、 L2 で考えるのではあまり意味が無い。 L2 ないし L3 キャッシュはHitレイテンシが大きく、 コアのリソース(レジスタ等)ではそのレイテンシを隠蔽できない。

とはいえ、現実にはL1キャッシュを256MB にできないし、 そんな大きなキャッシュだとL1キャッシュヒットレイテンシを 隠せないから同じ事だけれど。

キャッシュを生かすためにはキャッシュ以外の性能向上手法と組み合わせて相乗効果を狙うしかないと思う。

結論のこれは正しい。 けれど、いろいろとしがらみがあるのでなかなかね。

BlueLightningはコードサイズの小さいDOS時代のソフトでは爆速だったが、 Wiondows3.1ではそれなりの高速性に効果が縮小してしまった。これは、おそらくDOSとWindows3.1では扱うコードサイズが異なるために、キャッシュの効力に大きな違いが出てしまったためと考えられる。

この理由は絶対に違う。コードサイズではなくデータサイズに理由がある。

BlueLightning も Cx486 も unified (命令/データ共通) のキャッシュだったはずだ。 つまり、扱うデータが大きくなると、そのしわ寄せとして命令コードがキャッシュから追い出されるという副作用が現れる。つまり、 命令キャッシュとしての効果がほとんどなくなることになる。

ご存じの通り、Windows はたとえばフォントデータだけでも (DOSとは比較できないレベルで)でかいので、 ローカルキャッシュはどうでもいいデータによって 簡単に駆逐されてしまう。

現実には命令専用キャッシュなら16KBもあれば大抵は事足りる。 クリティカルとなる実行時間のほとんどはL1I$に十分乗る 小さなコード片で消費されているんだから。 ソフトウェアを書く人(でプロファイラで性能チューニングする人))なら、 特に意識せずに書いたプログラムでは特定の関数で実行時間の99%を占める、なんてのはしょっちゅう見ているはずだ。

# Pen4 のトレースキャッシュがアレなのは...

たまにしか実行されないコードが山のようにあって、それがたまに実行されることでキャッシュが汚れるので、ある程度の容量を超える命令キャッシュは性能が(すでに)頭打ちである。 命令フェッチ系は、それよりも分岐予測の方が頭がいたかろう。

それに較べると、データ方面はまだまだ細かい改善はあるはずなのだが。

ちうわけで、ソフトの肥大化はどうでもいいっちう話。(話が発散