あるキャッシュメモリの話

66
あるキャッシュメモリの話 第一回 カーネル/VM探検隊@名古屋 えとみ なるあき @nullnilaki

Transcript of あるキャッシュメモリの話

Page 1: あるキャッシュメモリの話

あるキャッシュメモリの話

第一回 カーネル/VM探検隊@名古屋えとみ なるあき

@nullnilaki

Page 2: あるキャッシュメモリの話

おやくそく

UVMはNetBSDおよびOpenBSDのメモリ管理システムのことです!

Page 3: あるキャッシュメモリの話

自己紹介• えとみ なるあき

• 港湾物流業界というニッチな世界で働いています

• 文系です

• 仕事ではCOBOLしか使った事が有りません A-VXでCOBOLを覚えました

• COBOL結構好き!

Page 4: あるキャッシュメモリの話

自己紹介コンテナ(仮想)を管理した事がある人は結構いると思いますが、コンテナ(物理)を管理した事がある人は会場には私だけのはずです!

Page 5: あるキャッシュメモリの話

さて、趣味の話

Page 6: あるキャッシュメモリの話

あるmmapの話

2014年3月9日に開催されたカーネル/VM探検隊@関西6でAlpha Station DS15にNetBSDを移植した際にbus_space_mmapのバグを発見し、PCIバスをもつAlphaマシンでフレームバッファを正しくマップできない問題を解決したという話をしました

Page 7: あるキャッシュメモリの話

Titanチップセット

Alpha Station DS15(1CPU)にはTitanチップセットが使われており、このチップセットは他にAlpha Station/Server DS25(2CPU)やAlpha Server ES45(4CPU)に使われています

Page 8: あるキャッシュメモリの話

Alpha Server DS25

CPU

Page 9: あるキャッシュメモリの話

Alpha Server DS25 CPU UNIT

Page 10: あるキャッシュメモリの話

MPカーネルは今日も元気です。

つまんねぇ!

Page 11: あるキャッシュメモリの話

AlphaStation DS15とAlpha Station DS25

同じCPU同じクロック同じチップセット

違いは二次キャッシュの容量!(2MBと8MB)

Page 12: あるキャッシュメモリの話

姫野ベンチdynamic allocate version Grid-size=M

★ DS15とDS25のスコアの差は キャッシュ容量が原因?

★ cccよりgccのほうがスコアが 良い?

★ Tru64とNetBSDではスコアが 倍以上違う?

Page 13: あるキャッシュメモリの話

NetBSDで性能向上させたい…

Page 14: あるキャッシュメモリの話

ページカラーリングキャッシュメモリでのスラッシングを防ぐ、あるいは積極的にキャッシュヒット率を向上させようとする物理ページ管理手法をページカラーリングと呼ぶ。

ページカラーリングはまた、仮想インデックスキャッシュのエイリアス問題への回避策としても使われた。

キャッシュは年々巨大化しているが、ページサイズは4Kバイトが一般的でこれはページング方式が一般化してから変わっていない。

物理アドレスをインデックスとするキャッシュでは、物理ページと仮想ページのマッピングによってはキャッシュ上で現に使用中のページの対応する位置が衝突してしまい、巨大なキャッシュを生かしきれない事態が発生することがある。

Wikipediaより

Page 15: あるキャッシュメモリの話

実験/sys/arch/alpha/alpha/dec_6600.c

#include <dev/cons.h>

+#include <uvm/uvm_extern.h>

#include <machine/rpb.h>

+static int external_cache_probe(int minsize, int width);

#ifdef KGDB #include <machine/db_machdep.h>@@ -102,6 +115,7 @@ void dec_6600_init(void) {

platform.family = "6600";

@@ -115,11 +129,52 @@ platform.device_register = dec_6600_device_register; platform.mcheck_handler = dec_6600_mcheck_handler;++ uvmexp.ncolors = atop(external_cache_probe(1024*1024, 6));+ /* enable Cchip and Pchip error interrupts */ STQP(TS_C_DIM0) = 0xe000000000000000; STQP(TS_C_DIM1) = 0xe000000000000000; }

external_cache_probeはLinuxのarch/alpha/kernel/setup.cを参考にして下さい

DS15の移植を通してL2キャッシュが設定されて無い事は知ってたのでL2キャッシュをプローブして適切に設定し、効果を実験

Page 16: あるキャッシュメモリの話

実験Alpha Station DS15Direct-mapped L2 Cache:2MB2048K Bcache detected; load hit latency 24 cycles, load miss latency 136cyclesuvmexp.colors = 256 (2048K / PAGE_SIZE) PAGE_SIZE = 8K

Alpha Server DS25Direct-mapped L2 Cache:8MB8192K Bcache detected; load hit latency 24 cycles, load miss latency 138cyclesuvmexp.ncolors = 1024 (8192K / PAGE_SIZE) PAGE_SIZE = 8K

colorの計算方法 = Cache size/assoc/PAGE_SIZE

L2キャッシュはちゃんとプローブされ、カラーも設定されています

Page 17: あるキャッシュメモリの話

姫野ベンチdynamic allocate version Grid-size=M

page coloringを設定したら性能ダダ下がり…(´;ω;`)ウッ

Page 18: あるキャッシュメモリの話

そもそもキャッシュメモリとは?キャッシュメモリ (cache memory) は、CPUなど処理装置がデータや命令などの情報を取得/更新する際に主記憶装置やバスなどの遅延/低帯域を隠蔽し、処理装置と記憶装置の性能差を埋めるために用いる高速小容量メモリのことである。

略してキャッシュとも呼ぶ。

コンピュータは以前から記憶装置や伝送路の性能が処理装置の性能に追いつけず、この差が全体性能に対するボトルネックとされてきた(ノイマンズ・ボトルネック)。そしてムーアの法則に基づく処理装置の加速度的な高性能化により現在ではますますこの差が拡大されている。

キャッシュメモリは、記憶階層の観点からこれを解消しようとするものである。

Wikipediaより

Page 19: あるキャッシュメモリの話

キャッシュメモリ

VIVTはあんまりない

TLB

VIPTは一次キャッシュに一般的に使われる

PIPTは二次キャッシュに一般的に使われる

Page 20: あるキャッシュメモリの話

仮想キャッシュ• プログラムの仮想アドレスを使ってキャッシュをインデックス

する

• メリット ☆ 高速 ☆ 仮想アドレスを使ってキャッシュを引くため アドレス変換を行わずに済み、 CPUにデータを素早く返す事が出来る

• デメリット ★ 容量が少ない ★ 仮想アドレスを使ってキャッシュを引くため エイリアス、曖昧性、DMA処理等で問題が発生する したがって適切なメンテナンスが必要

Page 21: あるキャッシュメモリの話

DMAの問題

デバイスがDMA転送を行う場合キャッシュの中身は考慮されないため、メインメモリが変更されたり読み出されたりするとキャッシュとメインメモリとの間のコヒーレンシが~(以下略…)

Page 22: あるキャッシュメモリの話

R10K and non-cache-coherent systems> boot -f pci(0)scsi(0)cdrom(4)rdisk(0)partition(8)ip3xboot51312+1792 entry: 0x80002000NetBSD/sgimips 6.1.5 Bootstrap, Revision 1.5devopen: pci(0)scsi(0)cdrom(4)rdisk(0)partition(0) type scsi file ip3x9676336+143472=0x95db74phys segment: 0xd000 @ 0x2000adding 0xd000 @ 0x2000 to freelist 0pmap_steal_memory: seg 2: 0x9be 0x9be 0xd50 0xd50pmap_steal_memory: seg 2: too small for 1176 pagespmap_steal_memory: seg 3: 0x1400 0x1400 0xfffe 0xfffeCopyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,2006, 2007, 2008, 2009, 2010, 2011, 2012The NetBSD Foundation, Inc. All rights reserved.Copyright (c) 1982, 1986, 1989, 1991, 1993The Regents of the University of California. All rights reserved.NetBSD 6.1.5 (INSTALL32_IP3x)total memory = 256 MB(6848 KB reserved for ARCS)avail memory = 235 MBmainbus0 (root): SGI-IP32 [SGI, b], 1 processorcpu0 at mainbus0: MIPS R12000 CPU (0xe23) Rev. 2.3 with unknown FPC type (0x900) Rev. 0.0cpu0: 64 TLB entries, 16MB max page sizecpu0: 32KB/64B 2-way set-associative L1 instruction cachecpu0: 32KB/32B 2-way set-associative write-back L1 data cachecpu0: 1024KB/64B 2-way set-associative write-back L2 data cachecrime0 at mainbus0 addr 0x14000000: rev 1.4 (CRIME_ID: 17592186044577)crmfb0 at mainbus0 addr 0x16000000: SGI CRIME Graphics Display Enginecrmfb0: initial resolution 1280x1024

カーネル読み込んでUVM初期化してデバイスプローブ

Page 23: あるキャッシュメモリの話

R10K and non-cache-coherent systemsahc1: aic7880: Ultra Wide Channel A, SCSI Id=0, 16/253 SCBsscsibus1 at ahc1: 16 targets, 8 luns per targetscsibus0: waiting 2 seconds for devices to settle...scsibus1: waiting 2 seconds for devices to settle...ahc0:parity error detected in Data-in phase. SEQADDR(0x7c) SCSIRATE(0x0)ahc0:parity error detected in Data-in phase. SEQADDR(0x7c) SCSIRATE(0x0)ahc0:parity error detected in Data-in phase. SEQADDR(0x171) SCSIRATE(0x0)ahc0:parity error detected in Data-in phase. SEQADDR(0x1c2) SCSIRATE(0x0)ahc0:Unexpected busfree in Message-out phase…SEQADDR == 0x172sd0 at scsibus0 target 2 lun 0: <\011\002\015, \004\016\005\023-318350\031, \023\00130> disk fixedahc0:Unexpected busfree in Message-out phaseSEQADDR == 0x172ahc0:Unexpected busfree in Message-out phase…>>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<ahc0: Dumping Card State in Data-in phase, at SEQADDR 0x7dCard was pausedACCUM = 0xf6, SINDEX = 0xb8, DINDEX = 0xa8, ARG_2 = 0x3HCNT = 0x40 SCBPTR = 0x1SCSISIGI[0x54] ERROR[0x0] SCSIBUSL[0x0] LASTPHASE[0x40]SCSISEQ[0x12] SBLKCTL[0x2] SCSIRATE[0x0] SEQCTL[0x10]SEQ_FLAGS[0x20] SSTAT0[0x0] SSTAT1[0x3] SSTAT2[0x0]<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>sg[0] - Addr 0xc0fdc50f : Length 128sd0(ahc0:0:2:0): ahc0: no longer in timeout, status = 0ahc0: Issued Channel A Bus Reset. 1 SCBs aborted

SCSIをプローブしてからおや!?O2のようすが…!

Page 24: あるキャッシュメモリの話

R10K and non-cache-coherent systems

Page 25: あるキャッシュメモリの話

エイリアスの問題

物理ページ=0x5e651000をマップする

2つの仮想アドレス0x8049000と0xdaf51000

仮想アドレス=0x8049000にabcdeを書き込んだ時、

ライン0x900は更新されるがライン0x100は更新されない

同じ物理アドレスをマップしているのに

キャッシュ内でデータが不一致

12345

Page 26: あるキャッシュメモリの話

物理キャッシュ• プログラムの物理アドレスを使ってキャッシュをインデックスする

• メリット ☆ エイリアス、曖昧性の問題が発生しない

• デメリット ★ アドレス変換が発生する (一次キャッシュのアクセスと並行してアドレス変換する)

★ OSのページ割当の方法によっては キャッシュスラッシングが発生して、性能が出ない

Page 27: あるキャッシュメモリの話

では、NetBSDではどうなっているのか?

Page 28: あるキャッシュメモリの話

ページカラーリング実装

uvm_page_physload()でvm_physmem構造体にOSが使える物理メモリの

範囲や優先度を登録

Page 29: あるキャッシュメモリの話

ページカラーリング実装

Page 30: あるキャッシュメモリの話

ページカラーリング実装

Page 31: あるキャッシュメモリの話

ページカラーリング実装

uvm_page_physload()でvm_physmem構造体にOSが使える物理メモリ

範囲や優先度を登録したので、使用出来る総ページ数を割り出す

Page 32: あるキャッシュメモリの話

ページカラーリング実装

Page 33: あるキャッシュメモリの話

ページカラーリング実装

バケツの数(カラー)と

OSが最終的に管理するページ数を割り出す

uvmexp.ncolorsが設定されていなければdefaultの1を設定

colorの設定方法は色々recolorするarchもある

uvm_page_init()

Page 34: あるキャッシュメモリの話

ページカラーリング実装例続き

Page 35: あるキャッシュメモリの話

ページカラーリング実装

pgflbucket構造体のサイズ×カラーの数×2(uvm.page_freeとuvm.cpus[0]->page_free用)+割り出したページ数 × vm_page構造体のサイズメモリを割り当てる

(例だと0x18d2438バイト)

uvm_pageboot_alloc()でメモリが奪われ、vm_physseg.startvm_physseg.avail_startが押し上げられる

例だと0x18d2438バイト -> 0x18d2ページ

vm_physseg.start = 0x1000↓vm_physseg.start = 0x28d2

uvm_page_init()

Page 36: あるキャッシュメモリの話

ページカラーリング実装

例続き

Page 37: あるキャッシュメモリの話

ページカラーリング実装

uvm_pagefree()で空ページ管理リストにvm_page構造体を割り当てていく

uvm_page_init()

vm_page構造体に管理する物理アドレスをセット

Page 38: あるキャッシュメモリの話

ページカラーリング実装

例続き

Page 39: あるキャッシュメモリの話

ページカラーリング実装

Page 40: あるキャッシュメモリの話

ページカラーリング実装 * o free * => pageq.list is entry on global free page queue * => listq.list is entry on per-CPU free page queue * => uanon is unused (or (void *)0xdeadbeef for DEBUG) * => uobject is unused (or (void *)0xdeadbeef for DEBUG) * => PQ_FREE is set in pqflags

uvm.page_freeとucpu->page_freeの二つの空きページリストに登録

uvm_pagefree()

Page 41: あるキャッシュメモリの話

ページカラーリング実装

例続き

Page 42: あるキャッシュメモリの話

ページカラーリング実装

例続き

Page 43: あるキャッシュメモリの話

ページカラーリング実装

例続き

Page 44: あるキャッシュメモリの話

ページカラーリング実装uvm_page_init()

uvm.page_init_doneにフラグを立てて、おしまい!

Page 45: あるキャッシュメモリの話

たくさんのmalloc()

uvmで匿名ページの割当はuvmfault_promote()が行っているuvm_pagealloc()でvm_page構造体(物理アドレス)を取得するuvm_pagealloc()の引数にページフォルトした仮想アドレスとUVM_FLAG_COLORMATCHがある事に注目

Page 46: あるキャッシュメモリの話

たくさんのmalloc()

uvm_pagealloc()の引数にUVM_FLAG_COLORMATCHが指定されている場合は、ページフォルトした仮想アドレスと同じ色のカラーを持つvm_page構造体(物理ページ)を割り当てる指定されていない場合は、カラーの色はラウンドロビン(順番に回る)でvm_page構造体(物理ページ)を割り当てる

uvm_pagealloc_start()はuvm_pagealloc()のdefine

Page 47: あるキャッシュメモリの話

たくさんのmalloc()uvm_pagealloc_start()

カラーが決まったので、uvm_pageallc_pgfl()で指定したカラーのvm_page構造体を取得する

Page 48: あるキャッシュメモリの話

たくさんのmalloc()

Page 49: あるキャッシュメモリの話

たくさんのmalloc()

カラーはラウンドロビンなので、1つカラーを進める

条件に有ったvm_page構造体を返す呼び出した関数でpmap_enter()して仮想アドレスと物理アドレスの紐付けする

Page 50: あるキャッシュメモリの話

エイリアス問題への対応

Page 51: あるキャッシュメモリの話

エイリアス問題への対応

Page 52: あるキャッシュメモリの話

エイリアス問題への対応

カラーが不一致のばあい、同じ物理アドレスをマップしているのに2つの仮想アドレスで読み書きをすると

キャッシュ内でデータが不一致

Page 53: あるキャッシュメモリの話

エイリアス問題への対応

カラーが一致するばあい、キャッシュラインが

競合するので常にキャッシュミスを起こし、

メモリへの読み書きが発生するため

データの不一致が発生しない

実際はさらにpmap()でゴニョゴニョ

Page 54: あるキャッシュメモリの話

Alpha Station XP1000XP1000は@impreza_gf8さんから譲っていただきました!

この機種はNetBSD1.4の頃からサポートされている(二次キャッシュのプローブはなし)

4096K Bcache detected;load hit latency 20 cycles,load miss latency 105 cycles

Page 55: あるキャッシュメモリの話

姫野ベンチdynamic allocate version Grid-size=M

昔のNetBSD 4を使って、page coloringを行うように変更した場合、性能向上が見られた!

2回目の実行で顕著に性能差が見られるのは1回目の内容がキャッシュに残っているため?だと思われる

Page 56: あるキャッシュメモリの話

姫野ベンチdynamic allocate version Grid-size=M

現在のNetBSD currentを使って、page coloringを行うように変更した場合、劇的に性能が落ちた!

Page 57: あるキャッシュメモリの話

UVM_FLAG_COLORMATCHが無い!

currentの処理

NetBSD4の頃はcolorの設定はラウンドロビンNetBSD6以降は、UVM_FLAG_COLORMATCHで仮想アドレスからカラーを指定する事も出来る(仮想アドレスキャッシュ対策)

Page 58: あるキャッシュメモリの話

大きいキャッシュに大きいページ、そこそこメモリ

COMPAQ Professional Workstation XP1000, 500MHz, s/n8192 byte page size, 1 processor.4096K Bcache detected; total memory = 512 MB(2128 KB reserved for PROM, 509 MB used by NetBSD)avail memory = 492 MB

このばあい、colorは512でしらべたところ、62831pageを扱っていた。

Page 59: あるキャッシュメモリの話

大きいキャッシュに大きいページ、そこそこメモリ

カラーが多すぎて、そのカラーのvm_page構造体が12個しかない…

Page 60: あるキャッシュメモリの話

大きいキャッシュに大きいページ、そこそこメモリ

おそらく,ログインプロンプトが出た時点ですでにいくつかの空きページリストはNULL

Page 61: あるキャッシュメモリの話

大きいキャッシュに大きいページ、そこそこメモリ

Page 62: あるキャッシュメモリの話

大きいキャッシュに大きいページ、そこそこメモリ匿名ページ割当関数のuvmfault_promote()でのUVM_FLAG_COLORMATCHを外した所、性能向上が見られました

Page 63: あるキャッシュメモリの話

大きいキャッシュに大きいページ、そこそこメモリ

Page 64: あるキャッシュメモリの話

ここで質問uvmfault_promote()のUVM_FLAG_COLORMATCH、取っては駄目なんでしょうか?どういうタイミングの時に匿名ページの割当でカラーを合わせる必要が有るのか?いまいち謎です

Page 65: あるキャッシュメモリの話

ここで質問DS25の場合、8MB 1024colorという巨大さでも、なぜか2回目が遅い?スラッシングはしてないはずだけれど?なぜ?

Page 66: あるキャッシュメモリの話

参考文献&お世話になった方々☆ UNIXカーネル内部解析 キャッシュとマルチプロセッサの管理☆ SOLARIS インターナル カーネル構造の全て☆ BSDカーネルの設計と実装 FreeBSD詳細☆ UNIXカーネルの設計☆ 最前線のUNIXのカーネル☆ BSD magazine 13号 NetBSDの設計と実装☆ NetBSD UVM page coloringメモ  http://togetter.com/li/203520☆ コンピュータアーキテクチャの話 12 キャッシュの構造や働き(上級編) - メモリエーリアス  http://news.mynavi.jp/column/architecture/012/

★ つついさんを始め、なまあたたかい目でアドバイスをくださる NetBSDなかたがた★ Alpha Station XP1000を譲って下さった、@impreza_gf8様★ Alpha Station 200を譲って下さった、@syuu1228様★ ふぁぼってくださる、フォロワーさん