Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
OSv malloc 日本語版
Search
Satoru Takeuchi
PRO
October 12, 2017
Programming
2
210
OSv malloc 日本語版
A briefly explanation of malloc() in OSv
Satoru Takeuchi
PRO
October 12, 2017
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
Linux環境のCPU上で10ミリ秒間に起こること
sat
PRO
3
73
HDDへのアクセス速度は位置によって変わる!??
sat
PRO
4
33
ボリュームマネージャLVM
sat
PRO
2
74
Best Practices of Production-Grade Rook/Ceph Cluster
sat
PRO
1
1.7k
OSSへの貢献をはじめたきっかけ、貢献で得たもの、やりたい人へのアドバイス(改)
sat
PRO
4
120
device mapperによるディスクI/O障害のエミュレーション 既存ターゲット編
sat
PRO
0
100
分散ストレージCephのデータ破壊検知修復機能は本当に動作するのか
sat
PRO
0
42
ディスクI/O障害のエミュレーション カーネルモジュール自作編
sat
PRO
0
39
分散ストレージはすごいぞ
sat
PRO
2
2.5k
Other Decks in Programming
See All in Programming
導入から5年が経って見えた Datadog APM 運用の課題
bgpat
2
540
孤独のCTOグルメという やや奇抜な企画をやった目的と効果
shoheimitani
3
1k
PHP8の機能を使って堅牢にコードを書く
fendo181
6
2.6k
Ruby製社内ツールのGo移行
bgpat
2
260
OpenTelemetry のサービスという概念について
azukiazusa1
1
390
今の SmartHR にエンジニアで入社するとどうなるの?
daisukeshinoku
1
400
設計の知識と技能で駆動するソフトウェア開発
masuda220
PRO
18
11k
WebComponentsで フレームワークを1ページに共存させる
webuilder240
0
150
Deep Dive 大規模システムアーキテクチャ/開発組織エンジニアリング / Deep Dive Large-Scale System Architecture, Development Organization Engineering
nrslib
15
2.9k
フロントエンドパフォーマンス 入門
shouta2
7
1.5k
SwiftUI, Jetpack Composeの導入で変化した「家族アルバム みてね」のアプリ開発体験
hicka04
6
400
PHP 8.3で追加されたjson_validate()を徹底的に深掘りしてみよう
mashirou1234
1
720
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
40
12k
StorybookのUI Testing Handbookを読んだ
zakiyama
10
4.5k
Navigating Team Friction
lara
177
13k
BBQ
matthewcrist
78
8.7k
Side Projects
sachag
451
41k
The Power of CSS Pseudo Elements
geoffreycrofte
58
4.9k
Visualization
eitanlees
135
14k
Rails Girls Zürich Keynote
gr2m
91
13k
Into the Great Unknown - MozCon
thekraken
10
830
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
1
1.2k
Intergalactic Javascript Robots from Outer Space
tanoku
266
26k
Building Adaptive Systems
keathley
29
1.8k
Transcript
OSv malloc(日本語版) Satoru Takeuchi <
[email protected]
>
はじめに • 本記事はOSv Advent Calendar[1] 21日目の記事 • 前提知識 ◦ OS/OSvについて、参考文献[2]程度の基礎知識
◦ C++の言語仕様 ◦ 基本的なアルゴリズム、データ構造の知識 ◦ Linux kernelのソースを読んだことがあれば、なおよい • 調査対象ソースは12/21日現在におけるupstreamのmaster branch[3] ◦ HEAD commit: f7d3ddd648b38789daa8287626a66863a780f139 ◦ 簡単のため、デバッグ機能やトレース機能、排他制御については無視 • 以後、パス名はOSv ソースコードのトップディレクトリからの相対パス
概要 • 定義はcore/mempool.cに存在: ファイルサイズは2K行弱 ◦ 実装はシンプル ◦ コメントにも”Our malloc() is
very coarse”とか書いてたりする • 小さなobjectの取得に特化(JVMのためか?) • カーネル空間でもユーザ空間でも全く同じmalloc()を使う ◦ それがOSv way ◦ linux kernelでいうとアプリがkmalloc()を直接呼ぶイメージ • 実際のobject獲得sizeは2^n >= 8バイト(nは正の整数)に切り上げられる ◦ 例) 4byte要求すると8byteのobjectを獲得
構成 • memory objectのsizeに応じて異なる仕組みを利用 ◦ <= 1KiB: mempool ◦ >
1KiB: page allocator user or kernel mempool (Linux kernelの sl[auo]bに相当) memory管理subsystem page allocator (Linux kernelの buddy allocatorに相当 malloc()/free()
簡単な実行の流れ malloc(size) - > std_malloc(size, align) (*1) sizeを2^n >= 8
(nは正の整数)バイトに切り上げ if (1KiB以下の獲得 && SMP用初期化後) # 後者はアプリなら常に真 malloc_pools[lg(n)].alloc() # mempoolより割り当て else if (1KiB<size<=4KiBの割り当て) memory::alloc_page() # page allocatorより1pageを割り当て else malloc_larger() # page allocatorより複数pageを割り当て # 3つの中で一番複雑な論理(説明は割愛) *1) posix_memalign()などによって明にalignmentを指定した場合は、もう少し 込み入った条件分岐をする。詳細はstd_malloc()のコードを参照
1KiB以下の割り当て • 前述のようにmempoolを使用 ◦ class malloc_pool(class poolを継承)によって管理 • 定義: “malloc_pool
malloc_pools[]” ◦ malloc()で獲得するobject sizeごとに存在するmempool ◦ 要素数はlg(page size)+1。x86_64ならpage sizeが4KiBなので12+1=13 ◦ それぞれsizeが1,2,4,8,...,4KiB,8KiBのsizeの割り当てに対応 ▪ 最後の8KiBの要素の必要性がよくわからない... ◦ アプリが使う範囲ではmempool[11,…,(page_size+1)]は未使用
mempoolのしくみ • slab allocator[4]のOSv版。page size以下の小さなsizeの割り当てに使用 ◦ class poolによって管理 # えらく汎用的な名前…
• 8byteから4KiBまでのsizeのobjectを扱う ◦ size <=1KiB: 1page内に複数objectを配置 ◦ 1KiB < size <= 4KiB: 1page内に1object • MP環境におけるスケーラビリティ向上のためのper-CPU cacheを持つ ◦ 参照の局所性により、object獲得時に自CPUが最近使用した、つまり cacheに残っているmemoryを使える可能性が向上 ◦ CPUごとの領域だけ使っている限りは、排他制御不要 • これ以上の詳細は”Memory allocation strategy”で始まるcommentや、ソース コードを参照
page allocatorのしくみ • page sizeのmemory割り当て ◦ class page_range_allocatorによって管理 • L1,
L2という2levelのcacheを持つ ◦ L1: per-CPU cache ◦ L2: global cache • cacheの下の最下層をglobal page allocatorと呼ぶ kernel subsystem (mempool含む) L1 cache (per-CPU cache) L2 cache (全CPUで共有) global page allocator page allocator
page allocator: L1 cache • per-CPUのcache • struct l1を用いて管理 ◦
cacheするpage数 <=l1::max(512) • 定義: “l1 percpu_l1[<CPU数>]” • UI: 名前が*_localなら、内部で同期獲得/開放しない ◦ page獲得: l1::alloc_page{,_local} ◦ page開放: l1::free_page{,_local} • L2 cacheとのインターフェイス ◦ 非同期: per-CPU thread(“page_pool_l1_<cpu>”)を用いる ▪ 残数 < l1::max*¼ => 複数pageを獲得 ▪ 残数 > l1::max*¾ => 複数pageを開放 ◦ 同期: 残数が0, l1::maxになれば、それぞれ同期的に複数pageを獲得/開 放
page allocator: L2 cache • 全CPU共通のcache • class l2を用いて管理 ◦
cacheするpage数は最多でl2::max) • (L1 cacheが使う)UI: 名前が”try_*”なら、内部で同期獲得/開放しない ◦ 複数page獲得: l2::{try_,}alloc_page_batch ◦ 複数page開放: l2::{try_,}free_page_batch • global page allocatorとのインターフェイス • 非同期: per-CPU thread(“page_pool_l2”)を用いる ◦ 残数 < l2::max*¼ => 複数pageを獲得 ◦ 残数 > l2::max*¾ => 複数pageを開放 ◦ 同期: 残数が0, l2::maxになれば、それぞれ同期的に複数pageを獲得/開 放
page allocator: global page allocator • OSvのメモリ管理subsystem最深部に存在するコンポーネント • systemの生の空きpageを管理 •
今回は時間の都合により、説明を割愛
参考文献 1. OSv Advent Calendar2014 http://qiita.com/advent-calendar/2014/osv 2. OSvのご紹介 in OSC2014
Tokyo/Fall, Takuya ASADA, Cloudius Systems http://www.slideshare.net/syuu1228/osv-in-osc2014-tokyofall 3. OSvのsource code https://github.com/cloudius-systems/osv 4. slab allocation at Wikipedia http://en.wikipedia.org/wiki/Slab_allocation 5. mallocの旅(Glibc編), こさき@ぬまづ http://www.slideshare.net/kosaki55tea/glibc-malloc
おまけ: OSvのコードを読んでみた感想 • malloc()の実装を読むはずが、結局カーネルのメモリ管理のコードをかなり読む はめに陥った。が、勉強になったのでよしとする • ソースがコンパクトで、今やすっかり巨大化したLinux kernelに比べると、はるか に読みやすい ◦
まだまだコード最適化による性能の伸びしろがある ◦ 息抜き/勉強用に気軽に読めるのでOSの学習にいいかも • malloc(size)以外にmalloc(size, align)という、posix_memalign()に似た関数も ある アプリにはexportしていないため、kernelのみが使用可能 C++のoverload機能があったからできる。ビバC++