ショボーン(´・ω・`)
sc420 login: SysRq : Trigger a crashdump
Memory for crash kernel (0x0 to 0x0) notwithin permissible range
PCI: BIOS Bug: MCFG area at e0000000 is not E820-reserved
PCI: Not using MMCONFIG.
ACPI: Getting cpuindex for acpiid 0x2
Mounting proc filesystem
Mounting sysfs filesys
ブートパラメタに書いたcrashkernel=128M@16M オプションが正しく認識されていることは
/proc/iomemにて確認済みだし。
おなじく、/proc/iomemにてe0000000 がreservedであることは確認できてるんだけど・・・
むむむ・・・
- 関連記事
-
- Linux VM scalability effort メンバーになってしまった件について (2008/02/01)
- kdumpの設定ができん (2008/01/28)
- 2日まえぐらいに (2008/01/26)
- 関連記事
-
- kdumpの設定ができん (2008/01/28)
- 2日まえぐらいに (2008/01/26)
- クロスケーブルめどい (2008/01/26)
Linuxで起動時にパニックしちゃう場合シリアルケーブルつなげておかないとデバッグがほぼ不可能なのだよ。
で、帰ってみると衝撃の事実が!!
ぼくちんのWindowsマシンにはなんとシリアルポートがなかった。イマドキのWindowsってそうなのねwwww
しょうがないから、取って返してUSB - シリアル変換機も買ってきた。バカス。
てゆーか、ちょっとした善意で6千円も飛んでいくのは若干納得行かないような。むむ。
で、Linux側の設定なのだが/boot/grub/grub.confの以下の箇所を変更すればOK
default=3
timeout=5
#splashimage=(hd0,0)/grub/splash.xpm.gz
serial --unit=0 --speed=9600 --word=8 --parity=no --stop=1
terminal --timeout=10 serial console
hiddenmenu
title CentOS (2.6.18-53.1.4.el5PAE)
root (hd0,0)
kernel /vmlinuz-2.6.18-53.1.4.el5PAE ro root=/dev/VolGroup00/LogVol00 rhgb quiet
initrd /initrd-2.6.18-53.1.4.el5PAE.img
title kosatest
root (hd0,0)
kernel /vmlinuz-kosatest ro root=/dev/VolGroup00/LogVol00 rhgb quiet console=tty0 console=ttyS0,9600n8r
initrd /initrd-kosatest.img
参考URL
JF文書 :http://www.linux.or.jp/JF/JFdocs/Remote-Serial-Console-HOWTO/index.html
ITメディア: http://www.itmedia.co.jp/help/tips/linux/l0617.html
第3のペンギン: http://blog.miraclelinux.com/thethird/2007/02/linux_fb95.html
USBをシリアルコンソールに: http://www.irori.org/doc/usb-console.html
- 関連記事
-
- 2日まえぐらいに (2008/01/26)
- クロスケーブルめどい (2008/01/26)
- mem_notify v5を post してきた (2008/01/24)
だんだん飽きてきたので、誰か目新しいコメントくれんかのぅ
- 関連記事
-
- クロスケーブルめどい (2008/01/26)
- mem_notify v5を post してきた (2008/01/24)
- MALLOC_TRIM_THRESHOLD_ と MALLOC_MMAP_MAX_ パラメタについて (2008/01/23)
むらむらするな
- 関連記事
-
- Zijilstra と Jrsutela (2008/02/04)
- イリピー・オントール (2008/01/23)
- いまごろ年賀状とどいた (2008/01/08)
http://mkosaki.blog46.fc2.com/blog-entry-241.html
で書いた事とほぼ同じだけれど。
Linuxにおいて、CPU負荷を測定するベンチマークでは以下の環境変数を設定すると往々にして性能があがる。
% setenv MALLOC_TRIM_THRESHOLD_ -1
% setenv MALLOC_MMAP_MAX_ 0
MALLOC_TRIM_THRESHOLD_ はOSに未使用になったメモリを返却する契機をあらわしていて、-1は決して返却しない事を表す。
MALLOC_MMAP_MAX_ は最大mmap数で0は決してmmapせず、どんなに大きなメモリでもbrkを使ってメモリを取る事を意味する。
で、性能に効くのは(たいてい)MALLOC_MMAP_MAX_のほう。
glibcはアンチフラグメンテーションの観点から一定以上(たしかデフォルト1M)の大きさのmallocは内部で直接mmap呼び出しをするように変換される。
で、これがある種の状況下では、2重の意味で悪い効果をもたらす。
1.キャッシュコンフリクト
まあ、実装がへこいのですがmmap呼び出すときにキャッシュカラーリングのコードが
はいってないんです。
なので、戻り値アドレスが全部ページバウンダリにそろってしまっています。
なので複数スレッドがmalloc復帰値を同じようなアクセスパターンでアクセスしていくと
がんがんキャッシュコンフリクトします。
2.munmapネック
mmapしたやつはbrkでとったやつと違い、フリーリスト管理はせずに、アプリがfree(3)を
呼んだら、すぐさまOSにmunmapする実装になっています。
で、特に大規模SMPにおいて、munmapはmmapと違ってlazyに処理できないので、
非常にコストが高い操作である。と
大抵のアーキで全CPUに割り込みとばして空間そぎ落として返事がくるのをじっと
まっているので。
かつ、Linuxにおいてドライバが数ミリ秒ぐらい割禁とかするのはめずらしくないので、
一番遅いCPUに引っ張られてますます遅くなる。
もちろん、この環境変数を設定するとヒープフラグメンテーションが進みやすくなるので365日動き続ける業務アプリで設定するものは考え物であるが、ベンチマークの数字的には結構効果があるので、ベンチマーク屋さんは、オマジナイ代わりに試してみる価値はある。
おまじない代わり! ランキング!
- 関連記事
-
- mem_notify v5を post してきた (2008/01/24)
- MALLOC_TRIM_THRESHOLD_ と MALLOC_MMAP_MAX_ パラメタについて (2008/01/23)
- lkmlにtinyパッチ投げたら (2008/01/18)
うるへー、いいからやってみろ
と返信してしまった。
もうちょっと言葉遣いを考えましょう。反省。
- 関連記事
-
- MALLOC_TRIM_THRESHOLD_ と MALLOC_MMAP_MAX_ パラメタについて (2008/01/23)
- lkmlにtinyパッチ投げたら (2008/01/18)
- どおりで (2008/01/15)
おかげでLKMLで恥をかいたわい (馬゚∀゚鹿)♪
- 関連記事
-
- lkmlにtinyパッチ投げたら (2008/01/18)
- どおりで (2008/01/15)
- ついさっき (2008/01/15)
後は野となれ山となれ(゚д゚`)
- 関連記事
-
- どおりで (2008/01/15)
- ついさっき (2008/01/15)
- kzk benchその後 (2008/01/13)
2.6.24-rc6 +my patch ratio
-------------------------------------------------
rw_cp 59.32 58.60 98.79%
rw_fadv_cp 57.96 57.96 100.0%
mm_sync_cp 69.97 61.68 88.15%
mm_sync_madv_cp 69.41 62.54 90.10%
mw_cp 61.69 63.11 102.30%
mw_madv_cp 61.35 61.31 99.93%
ratioが100以下が高速化である。
勝手な理屈だが10%程度以上の高速化をsignificantと定義している。
パッチの説明だが、メモリが不足したときのページ回収論理においてaccessed bitが立っていたページを残し、それ以外を捨てる。という論理があるのだが、そこに
・周辺のページがずっと、accessed bitが立ち続けていたらmmaped copy中とみなしてaccessed bitを無視する
という論理がいれてある。
本格的にやるにはpage->flagsにフラグビットを追加しないといけないが、Linuxにおいてそれはフレームの元なので、強引に避けてある。
来週ぐらいにlinux-mmに投げてみるべ
---
mm/vmscan.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 43 insertions(+), 3 deletions(-)
Index: linux-2.6.24-rc6-cp3/mm/vmscan.c
===================================================================
--- linux-2.6.24-rc6-cp3.orig/mm/vmscan.c 2008-01-13 21:58:03.000000000 +0900
+++ linux-2.6.24-rc6-cp3/mm/vmscan.c 2008-01-13 22:30:27.000000000 +0900
@@ -446,13 +446,18 @@ static unsigned long shrink_page_list(st
struct pagevec freed_pvec;
int pgactivate = 0;
unsigned long nr_reclaimed = 0;
+ unsigned long nr_scanned = 0;
+ LIST_HEAD(l_mapped_pages);
+ unsigned long nr_mapped_page_activate = 0;
+ struct page *page;
+ int reference_checked = 0;
cond_resched();
pagevec_init(&freed_pvec, 1);
+retry:
while (!list_empty(page_list)) {
struct address_space *mapping;
- struct page *page;
int may_enter_fs;
int referenced;
@@ -466,6 +471,7 @@ static unsigned long shrink_page_list(st
VM_BUG_ON(PageActive(page));
+ nr_scanned++;
sc->nr_scanned++;
if (!sc->may_swap && page_mapped(page))
@@ -493,11 +499,17 @@ static unsigned long shrink_page_list(st
goto keep_locked;
}
- referenced = page_referenced(page, 1);
- /* In active use or really unfreeable? Activate it. */
- if (sc->order <= PAGE_ALLOC_COSTLY_ORDER &&
- referenced && page_mapping_inuse(page))
- goto activate_locked;
+ if (!reference_checked) {
+ referenced = page_referenced(page, 1);
+ /* In active use or really unfreeable? Activate it. */
+ if (sc->order <= PAGE_ALLOC_COSTLY_ORDER &&
+ referenced && page_mapping_inuse(page)) {
+ nr_mapped_page_activate++;
+ unlock_page(page);
+ list_add(&page->lru, &l_mapped_pages);
+ continue;
+ }
+ }
#ifdef CONFIG_SWAP
/*
@@ -604,7 +616,31 @@ keep:
list_add(&page->lru, &ret_pages);
VM_BUG_ON(PageLRU(page));
}
+
+ if (nr_scanned == nr_mapped_page_activate) {
+ /* may be under copy by mmap.
+ ignore reference flag. */
+ reference_checked = 1;
+ list_splice(&l_mapped_pages, page_list);
+ goto retry;
+ } else {
+ /* move active list just now */
+ while (!list_empty(&l_mapped_pages)) {
+ page = lru_to_page(&l_mapped_pages);
+ list_del(&page->lru);
+ prefetchw_prev_lru_page(page, &l_mapped_pages, flags);
+
+ if (!TestSetPageLocked(page)) {
+ SetPageActive(page);
+ pgactivate++;
+ unlock_page(page);
+ }
+ list_add(&page->lru, &ret_pages);
+ }
+ }
+
list_splice(&ret_pages, page_list);
+
if (pagevec_count(&freed_pvec))
__pagevec_release_nonlru(&freed_pvec);
count_vm_events(PGACTIVATE, pgactivate);
パッチぐらいいくらでも見せますがな
- 関連記事
-
- ついさっき (2008/01/15)
- kzk benchその後 (2008/01/13)
- 2.6.24-rc6-mm1がうごかねー (2008/01/13)
しかし、i386が動かなくなるようなパッチを投げる気がしれんな。
とりあえず、mem_notify v4の作業はすべて完了。
来週頭ぐらいに一度なげるべ。
- 関連記事
-
- kzk benchその後 (2008/01/13)
- 2.6.24-rc6-mm1がうごかねー (2008/01/13)
- 実態を糊塗して成果を大きく見せる方法 (2008/01/03)
http://www.rubyist.net/~matz/20080108.html#p03
McAfee throws some FUD at the GPL - The INQUIRER
McAfeeがGPLに対するFUDを行ったという話。In its annual report, Windows security software vendor McAfee told its investors that open source software licence terms it vaguely characterised as " ambiguous" might "result in unanticipated obligations regarding our products."
投資家に対する年次報告においてMcAfeeは以下のように報告した。「オープンソースソフトウェアの曖昧な性質によって、我々のプロダクトに予期しない義務が発生する可能性がある」
"To the extent that we use 'open source' software, we face risks," McAfee stated.
「オープンソースソフトウェアの利用によって、我々はリスクに直面している」
裏は取っていないけど、これが真実であるとしたら、かなりひどい話。
うーん、そうは思わなかったりする。
投資家向けの年次報告書は、株価が落ちたときにそのリスクが前年度の報告書に書いてないと、だましたなー扱いで訴えられて泣きっ面に蜂というか一粒で二度おいしいというか、そういう痛い状況になってしまうので悪い方向に過敏に書くのは、あっちの世界ではむしろ良心的行動。
Windowsが没落することにより株価下落の可能性があるのは事実なんだし。
むしろannual reportの内容を空気読まずにギークに転載しちゃうのがよくねーと思うだわよ。別にプレスリリースとかで語ったわけじゃないんでしょ。
違う世界の文化も受け入れてあげるべきだと思うな
とか思ったり、思わなかったり。
駄文。。。
- 関連記事
-
- 富士通、HDD用ヘッド事業を3月末に終息 (2009/01/27)
- McAfeeがGPLに対するFUDを行ったという話 (2008/01/09)
- さくらインターネット債務超過の件 (2007/11/28)
いくら引越しして転送されてるからって遅すぎないか?!
#10枚ぐらいいっきに来たので、差出人のみなさんは1/1に届くようにしていたと思われる
いまから返事を書いても時期はずれだしなー。どうしようかなー
それをいいわけにして返事をさぼるかー
- 関連記事
-
- イリピー・オントール (2008/01/23)
- いまごろ年賀状とどいた (2008/01/08)
- あけました! (2008/01/01)
エロサイト誘導とかは特に実害ないので放置を基本にしているが、さすがにクラッシュやらHDDフォーマットやらを仕込まれると人様に迷惑がかかるので、消したくなる。
んでイタチゴッコ ←いまここ
はげしくメドイ
なんかいいフィルター方法ないかしらね
- 関連記事
-
- 今日のLinus (2008/04/29)
- spamコメントむかつく (2008/01/04)
- MyMiniCityつくった(^^) (2007/12/19)
んで、最近佐藤優の一連の著作を読みまくったのでインテリジェンス業界のやり口がすこし分かってきたので、自分のやる気に対して応用してみるテスト。
成果が5%。と書くとまるでダメな子みたいであるが、ここで視点を変えてみよう。
うちのマシンにおいてはディスクI/O性能がだいたい20MB/sであることが経験則で分かっている。なので、1(GB)/20(MB/s)=50sがソフトネックがなく、ディスクシークも発生しなかった時の速度。
だから、58.17s -> 55.03s というのはオーバヘッドが8.17 -> 5.03という見方もできる!
つまり
,.ィ , - 、._ 、
. ,イ/ l/  ̄ ̄`ヽ!__
ト/ |' { `ヽ. ,ヘ
N│ ヽ. ` ヽ /ヽ / ∨
N.ヽ.ヽ、 , } l\/ `′
. ヽヽ.\ ,.ィイハ | _|
ヾニー __ _ -=_彡ソノ u_\ヽ、 | \ 実は+40%の
.  ゙̄r=<‐モミ、ニr;==ェ;ュ<_ゞ-=7´ヽ > 高速化に成功して
. l  ̄リーh ` ー‐‐' l‐''´冫)'./ ∠__ いたんだよ!!
゙iー- イ'__ ヽ、..___ノ トr‐' /
l `___,.、 u ./│ /_
. ヽ. }z‐r--| / ト, | ,、
>、`ー-- ' ./ / |ヽ l/ ヽ ,ヘ
_,./| ヽ`ー--‐ _´.. ‐''´ ./ \、 \/ ヽ/
-‐ '''"  ̄ / :| ,ゝ=< / | `'''‐- 、.._
/ !./l;';';';';';';\ ./ │ _
_,> '´|l. ミ:ゝ、;';';_/,´\ ./|._ , --、 | i´!⌒!l r:,=i
. | |:.l. /';';';';';|= ヽ/:.| .|l⌒l lニ._ | ゙ー=':| |. L._」 ))
l. |:.:.l./';';';';';';'! /:.:.| i´|.ー‐' | / | |. ! l
. l. |:.:.:.!';';';';';';';'| /:.:.:.:!.|"'|. l' │-==:|. ! ==l ,. -‐;
l |:.:.:.:l;';';';';';';';| /:.:.:.:.:| i=!ー=;: l | l. | | / //
l |:.:.:.:.:l;';';';';';';'|/:.:.:.:.:.:.!│ l l、 :| | } _|,.{:: 7 ))
l |:.:.:.:.:.:l;';';';';'/:.:.:.:.:.:.:.:| |__,.ヽ、__,. ヽ._」 ー=:::レ' ::::::|; 7
. l |:.:.:.:.:.:.l;';';'/:.:.:.:.:.:.:.:.:.|. \:::::\::::: ヽ ::::::!′ :::| .:/
. l |:.:.:.:.:.:.:∨:.:.:.:.:.:.:.:.:.:.:.! /ヽ::: `::: :::: ....::..../
・・・・だめだ
無理がありすぎる。
やる気をだすなんて無理。
- 関連記事
-
- 2.6.24-rc6-mm1がうごかねー (2008/01/13)
- 実態を糊塗して成果を大きく見せる方法 (2008/01/03)
- marceloから返事来た (2008/01/03)
/::::i::::、:::ヽ、:::::\:ヽ:\::::::ヽ:::、::ヽ::、:',
/::i|::l::ト、ヽ::、:::ヽ:、::::::\::ヽ::::l::::ヽ::i:::i:::!
/:/:!:::!:|::ヽ:\ヽ::::、:\::::ヽ:::ヽ!::::::i::|:::!::!
!ハ::|::::i::l:|心、:ヽ::\:ヽ_\、\:::ヽ:::|!::|:|i
i、:!:|:、N{、ヒjヽゝ\ヾイ ヒj >、ヽi:、|!:|:l
ヽ:!::トヽ ̄ l! ` ` ̄´ |::l::|:|j:,!:! 駄目だこいつ
ト、::! u j |::/lj:::!リ
ヾ、 丶 - u リイ:|リ 早くなんとかしないと……
リヽ ‐、ー- 、_ /イ:::i
rー'"ト:l゙、  ̄ ./ , |::!
/ ヘ ヾ ヽ、 _,. ' / |:'
- 関連記事
-
- 実態を糊塗して成果を大きく見せる方法 (2008/01/03)
- marceloから返事来た (2008/01/03)
- 最新Linuxでmm_mun_cpが実行できん (2008/01/03)
この定理に関して、私は真に驚くべき証明を見つけたが、この32bitアドレス空間はそれをmmapするには狭すぎる
と遺言されてしまっているらしい。南無
- 関連記事
-
- marceloから返事来た (2008/01/03)
- 最新Linuxでmm_mun_cpが実行できん (2008/01/03)
- 続々kzk benchが斬る (2008/01/03)
ソースを読みながらつらつらと考えてみたところ、mw_madv_cpでは、どうやら以下のルートで処理が進んでいるようだと分かってきました
前提知識ですが、Linuxにおいてはページはactiveリストとinactiveリストという2本の
LRUリストで管理されています(/proc/meminfoでのactive, inactive欄ね)
なんで、二本あるのかというとページ回収するときに頻繁に参照されているページを
最初から除外できるとおいしいでしょ?ってぐらいに理解しておいてください。
名前から分かるようにinactiveなほうが、捨てられる(or スワップアウトされる)直前のページ群ね。
1.まずmmapedなメモリアクセスを契機にread aheadが走ります。
で、read aheadは読み込んだページをinactiveリストにつなぎます
2.memcpy君が実際にメモリに触ります。ここでPTEのaccess bittがONになります。
3.どこかのタイミングでメモリが足りなくなってページ回収が走ります
(おいらのマシンは512Mしかないので、オンメモリで1Gコピーは絶対ありえない)
4.ここでスワップアウトしようかなーとinactiveリストを舐めているときに、access bitが
立っていると、なんだ使ってるじゃんということでそのページはactive listに移されます。
今回のケースではなんと全ページactive list行き
5.でLinuxのメモリ管理のポリシーとしてmapped pageと普通のファイルキャッシュは
activeからinactiveへの転落しやすさが違います。
まあ、普通に考えてメモリとしてアクセスするページのほうがランダムアクセスされる
可能性は高いわけで、シーケンシャルアクセスの可能性が高いmmapされていない
普通のファイルキャッシュを先に捨てていくのは合理的といえなくもない。
6.で、memory pressureが十分高まるまではactive listに残ったreadメモリが
ぜんぜん捨てられないので、write用のメモリ領域がすくなくなってくる。
で、どうしようもなくなると、ある閾値を超えたところで一気にinactive listに
移動するので流れ作業が乱れまくり。と
実際iostatで見るとI/O転送レートがほんとうに上下しまくる
なので、4の段階でシーケンシャルアクセスだよん。とmadviseされていたら、
active listにいかない。というパッチをこさえてみました。
結果は以下。ようやっとrw_cp並。
約5%の性能向上やね。
+(eval):1> sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
+./test.sh:10> time ./rw_cp testfile1G testfile1G2
0.04user 4.40system 0:55.81elapsed 7%CPU (0avgtext+0avgdata 0maxresident)k
2099512inputs+2097152outputs (0major+91minor)pagefaults 0swaps
+(eval):1> sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
+./test.sh:17> time ./mw_madv_cp testfile1G testfile1G2
0.00user 5.11system 0:55.03elapsed 9%CPU (0avgtext+0avgdata 0maxresident)k
2099368inputs+2097152outputs (1major+262233minor)pagefaults 0swaps
ちなみに、あてたパッチは以下
---
mm/vmscan.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
Index: linux-2.6.24-rc6-cp2/mm/vmscan.c
===================================================================
--- linux-2.6.24-rc6-cp2.orig/mm/vmscan.c 2008-01-03 02:05:11.000000000 +0900
+++ linux-2.6.24-rc6-cp2/mm/vmscan.c 2008-01-03 02:25:39.000000000 +0900
@@ -435,6 +435,30 @@ cannot_free:
return 0;
}
+static bool page_sequential_mapped(struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+ pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+ struct vm_area_struct *vma;
+ struct prio_tree_iter iter;
+ bool ret = true;
+
+ if (!page_mapped(page))
+ return false;
+
+ spin_lock(&mapping->i_mmap_lock);
+ vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ if (!VM_SequentialReadHint(vma)) {
+ ret = false;
+ break;
+ }
+ }
+ spin_unlock(&mapping->i_mmap_lock);
+ return ret;
+}
+
+
+
/*
* shrink_page_list() returns the number of reclaimed pages
*/
@@ -496,7 +520,8 @@ static unsigned long shrink_page_list(st
referenced = page_referenced(page, 1);
/* In active use or really unfreeable? Activate it. */
if (sc->order <= PAGE_ALLOC_COSTLY_ORDER &&
- referenced && page_mapping_inuse(page))
+ referenced && page_mapping_inuse(page) &&
+ !page_sequential_mapped(page))
goto activate_locked;
#ifdef CONFIG_SWAP
が、しかし、このパッチは以下の致命的な欠点がある
・普通の人はmadviseなんか使わないので、明示的なヒントなしにシーケンシャルアクセスか
ランダムアクセスかを推測しないと本質的な解決にはならない。
(このパッチではmw_cpはぜんぜん高速化されていない)
なんだけど、mmapでそれを推測するのはめちゃくちゃ難しいぞ・・・
・そもそも、lock dependency的に行儀が悪いので、たまにデッドロックしてOSハングする
↑バカスwww
今後のworkとしては
・mw_cpのmajor fault量からいってread aheadがうまく動いていないので動くようにする
・read aheadがうまくHITしているときはシーケンシャルアクセスとみなすようにする
の2段階で作業を進めればいいと思われる。
てか、本当になにをやっているんだか
なにをやってるの? ランキング!
- 関連記事
-
- 最新Linuxでmm_mun_cpが実行できん (2008/01/03)
- 続々kzk benchが斬る (2008/01/03)
- kzk benchつづき (2008/01/02)
改造しやすいようにと、最新カーネルビルドして再テストしたらめっさ速いんでやんの。
やる気なくすわー
2.6.24-rc6での結果は以下
[kosaki@sc420 copy]$ ./test.sh
+./test.sh:10> time ./rw_cp testfile1G testfile1G2
0.06user 4.70system 0:56.17elapsed 8%CPU (0avgtext+0avgdata 0maxresident)k
2099456inputs+2097152outputs (0major+106minor)pagefaults 0swaps
+./test.sh:12> time ./rw_fadv_cp testfile1G testfile1G2
0.04user 4.54system 0:53.10elapsed 8%CPU (0avgtext+0avgdata 0maxresident)k
2099448inputs+2097152outputs (0major+107minor)pagefaults 0swaps
+./test.sh:14> time ./mm_sync_cp testfile1G testfile1G2
0.46user 3.52system 1:07.61elapsed 5%CPU (0avgtext+0avgdata 0maxresident)k
2099904inputs+2097160outputs (32772major+491656minor)pagefaults 0swaps
+./test.sh:16> time ./mm_mun_cp testfile1G testfile1G2
0.54user 3.55system 1:06.09elapsed 6%CPU (0avgtext+0avgdata 0maxresident)k
2100168inputs+2097160outputs (32773major+491654minor)pagefaults 0swaps
+./test.sh:18> time ./mm_sync_madv_cp testfile1G testfile1G2
0.78user 2.91system 1:17.44elapsed 4%CPU (0avgtext+0avgdata 0maxresident)k
2100136inputs+2097160outputs (8major+524420minor)pagefaults 0swaps
+./test.sh:20> time ./mm_mun_madv_cp testfile1G testfile1G2
0.76user 3.22system 1:09.66elapsed 5%CPU (0avgtext+0avgdata 0maxresident)k
2100224inputs+2097168outputs (8major+524422minor)pagefaults 0swaps
+./test.sh:22> time ./mw_cp testfile1G testfile1G2
0.00user 4.94system 0:59.05elapsed 8%CPU (0avgtext+0avgdata 0maxresident)k
2100288inputs+2097408outputs (16391major+245892minor)pagefaults 0swaps
+./test.sh:24> time ./mw_madv_cp testfile1G testfile1G2
0.00user 5.06system 0:58.17elapsed 8%CPU (0avgtext+0avgdata 0maxresident)k
2100352inputs+2097152outputs (8major+262276minor)pagefaults 0swaps
相変わらず最速値はふつうのread-writeでのコピーですが、このぐらいだとほかの方法でもぜんぜん許せる気がします
mmap-mmapコピーの高速化(約2倍)もすごいし、madviseかけたときのページフォルトの数が約1/1000になっています。
高負荷時に効きそうですね。
・・・
・・・・・・
・・・・・・・・・・・・
さて、次のネタをさがすか
憂鬱! ランキング!
- 関連記事
-
- 続々kzk benchが斬る (2008/01/03)
- kzk benchつづき (2008/01/02)
- kzk benchの追試 (2008/01/01)
むかーし、極一部で話題になっていたkzk bench(CP速度対決ベンチ)について、時間の余裕ができたので追試した
なお、キャッシュを追い出さないと2番手以降が最初からキャッシュに乗っていて有利すぎるので、テスト用のシェルスクリプトはちょっと変えた(以下参照)
#!/bin/zsh -x
SRC=testfile1G
DST=testfile1G2
TIMEX=time
PREPARE='rm $DST;sync;sync;sync;sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"'
REPEAT=1
eval $PREPARE
(repeat $REPEAT $TIMEX ./rw_cp ${SRC} ${DST})
eval $PREPARE
(repeat $REPEAT $TIMEX ./rw_fadv_cp ${SRC} ${DST})
eval $PREPARE
(repeat $REPEAT $TIMEX ./mm_sync_cp ${SRC} ${DST})
eval $PREPARE
(repeat $REPEAT $TIMEX ./mm_mun_cp ${SRC} ${DST})
eval $PREPARE
(repeat $REPEAT $TIMEX ./mm_sync_madv_cp ${SRC} ${DST})
eval $PREPARE
(repeat $REPEAT $TIMEX ./mm_mun_madv_cp ${SRC} ${DST})
eval $PREPARE
(repeat $REPEAT $TIMEX ./mw_cp ${SRC} ${DST})
eval $PREPARE
(repeat $REPEAT $TIMEX ./mw_madv_cp ${SRC} ${DST})
んで、結果は以下
+./test.sh:10> time ./rw_cp testfile1G testfile1G2
0.06user 2.17system 0:58.52elapsed 3%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+107minor)pagefaults 0swaps
+./test.sh:12> time ./rw_fadv_cp testfile1G testfile1G2
0.06user 2.38system 0:54.98elapsed 4%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+107minor)pagefaults 0swaps
+./test.sh:14> time ./mm_sync_cp testfile1G testfile1G2
0.11user 2.48system 1:43.94elapsed 2%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (35151major+489276minor)pagefaults 0swaps
+./test.sh:16> time ./mm_mun_cp testfile1G testfile1G2
0.10user 2.50system 1:42.32elapsed 2%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (35037major+489391minor)pagefaults 0swaps
+./test.sh:18> time ./mm_sync_madv_cp testfile1G testfile1G2
0.43user 3.52system 2:03.72elapsed 3%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (8605major+515805minor)pagefaults 0swaps
+./test.sh:20> time ./mm_mun_madv_cp testfile1G testfile1G2
0.31user 3.36system 1:41.93elapsed 3%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (8542major+515869minor)pagefaults 0swaps
+./test.sh:22> time ./mw_cp testfile1G testfile1G2
0.00user 2.27system 1:25.39elapsed 2%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (18497major+243773minor)pagefaults 0swaps
+./test.sh:24> time ./mw_madv_cp testfile1G testfile1G2
0.00user 2.94system 1:09.59elapsed 4%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (8490major+253760minor)pagefaults 0swaps
以下、ここから分かる考察
・syncするとまじ遅い。(が、それはあたりまえなので気にしない)
・rw_cpはぜんぜんページフォルトしてない。これが速度の秘密っぽい
・mmap-mmapコピーはまじで性能悪い。びっくり
・madviceするとページフォルト減る。これが速度向上の理由っぽげ
と、いうわけで、最速のrw_cpと最遅のmm_mun_cp(あ、syncいれてるのは遅くてあたりまえだから除いた)で動作中のiostatとvmstatをじーーーと見てみる。
まず、rw_cp
[kosaki@sc420 ~]$ iostat /dev/sda 10 -m
Linux 2.6.18-53.el5xen (sc420) 2008年01月01日
avg-cpu: %user %nice %system %iowait %steal %idle
1.55 0.00 2.15 67.48 0.00 28.82
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 356.94 13.01 23.08 130 231
avg-cpu: %user %nice %system %iowait %steal %idle
1.75 0.00 3.20 68.87 0.05 26.13
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 360.50 18.93 19.40 189 194
avg-cpu: %user %nice %system %iowait %steal %idle
1.45 0.00 3.50 60.83 0.00 34.22
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 339.90 19.38 15.58 193 155
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 5 266 3 0 377 0 0 6262 6791 533 563 1 2 10 88 0
0 2 266 4 0 374 0 0 11797 14728 650 863 1 7 35 58 0
0 2 266 4 0 383 0 0 9810 8648 598 732 2 4 34 61 0
0 2 266 4 0 383 0 0 11689 12560 595 795 1 6 41 52 0
0 3 266 3 0 382 0 0 10872 10546 597 779 1 5 40 54 0
1 2 266 2 0 383 0 0 10807 9652 583 779 1 4 36 58 0
1 3 266 3 0 381 0 0 10392 10254 590 786 2 5 39 55 0
0 0 266 4 0 381 0 0 5988 5431 407 559 1 3 61 35 0
0
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free inact active si so bi bo in cs us sy id wa st
0 2 266 3 368 30 0 0 15119 11773 591 658 1 2 48 49 0
0 7 266 3 373 25 0 0 14971 21259 615 711 1 2 10 86 0
0 4 266 3 372 26 0 0 18725 19391 672 761 2 3 19 77 0
1 5 266 3 371 26 0 0 18352 19450 628 742 2 3 25 71 0
0 5 266 3 371 26 0 0 19425 18876 603 748 2 3 14 81 0
0 0 266 9 369 26 0 0 7363 13603 406 540 1 2 62 34 0
0
次はmm_mun_cp
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 378.59 11.45 12.67 114 127
avg-cpu: %user %nice %system %iowait %steal %idle
0.95 0.00 4.55 60.33 0.00 34.17
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 329.40 10.03 10.49 100 104
avg-cpu: %user %nice %system %iowait %steal %idle
1.75 0.00 4.36 54.78 0.00 39.11
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 319.60 10.41 9.51 104 95
avg-cpu: %user %nice %system %iowait %steal %idle
1.05 0.00 4.79 55.31 0.05 38.80
Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 323.52 10.06 10.27 100 102
[kosaki@sc420 ~]$ vmstat 10 -S M
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 3 266 237 0 127 0 0 792 757 125 258 2 1 89 8 0
0 9 266 66 0 302 0 0 12087 15989 841 854 1 7 26 66 0
2 3 266 16 0 362 0 0 7506 6304 608 617 1 2 46 51 0
9 6 267 3 0 378 0 0 11665 12942 669 829 1 5 29 65 0
0 5 267 3 0 381 0 0 10360 9941 595 794 1 5 38 55 0
0
[kosaki@sc420 ~]$ vmstat 10 -S M -a
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free inact active si so bi bo in cs us sy id wa st
0 4 266 166 189 52 0 0 793 757 125 258 2 1 89 8 0
0 11 266 65 202 138 0 0 8628 15499 708 668 1 7 22 69 0
0 4 266 13 335 56 0 0 7524 6934 609 618 1 2 45 52 0
2 4 267 9 229 165 0 0 11502 12703 661 821 1 6 30 63 0
0 3 267 3 258 142 0 0 10362 9550 593 794 1 4 39 56 0
0
一見して分かるのはiostatのIO転送速度がバッチリ違うところであるが、これは結果であって原因ではない。
なので、vmstatのほうをじーーーーとみる。
すると面白いことが分かった。rw_cpのほうはキャッシュがほぼすべてinactiveリストに載っているが、mm_mun_cpのほうは1/3ぐらいがactiveリストに残っているのだ。
すると仮説としては、
・Linuxのくそ重いページ回収まわりが遅いのが原因である
・が、rw_cpは幸運なことに、read aheadによってキャッシュに乗ったことが原因で最初から
inactive listにのった。
よって、たまたま、遅いルートに乗らなかった。
という仮説がうかぶ。
今度、シーケンシャルアクセスはactive listにのせないパッチを書いて試してみよう
- 関連記事
-
- kzk benchつづき (2008/01/02)
- kzk benchの追試 (2008/01/01)
- volanomark動いた (2008/01/01)
- 関連記事
-
- kzk benchの追試 (2008/01/01)
- volanomark動いた (2008/01/01)
- CentOSでvmlinuxってどうやって入手するの? (2008/01/01)
単にOprofileを使いたいだけなんだが。。。
CentOS5はインストール時にnativeとxenサポートが選べれるのだけれど、
yumのパッケージのkernel-develはnative版しかない。
最初にxenを選ぶのは罠って事?
PS
せっかく新年になったのだから新しいことをしようと、はてな人力検索に初挑戦
はてなポイントとか初めて買ったよ(^^;;
http://q.hatena.ne.jp/1199167805
- 関連記事
-
- volanomark動いた (2008/01/01)
- CentOSでvmlinuxってどうやって入手するの? (2008/01/01)
- seto_benchが再現できない件について (2008/01/01)
VIRT_CPU_ACCOUNTINGありのような挙動を示す。
少なくとも以下では改善しなかった
・usleep(0)がlibcレイヤでNOPにされているかとしんぱいしてsyscall(__NR_NANOSLEEP)に変更
・sysenterまわりの最適化が効きすぎているのかと思い、gcc --staticでテストプロをコンパイル
むーん、なんなんだろう。
てゆーか、そろそろ、興味を失ってきた。
これができても、肝心のスケジューラーがjiffiesべったりなので、Windowsなみに到達できそうにないし。
Let me demonstrate a benefit of VIRT_CPU_ACCOUNTING.
Here is a sample program:
-------------------------------------------------
#include
#include
/* 300 million */
#define LOOP 300000000
int main(int argc, char **argv)
{
unsigned long sum = 0;
int i;
int c = argc > 1 ? atoi(argv[1]) : LOOP;
printf("sum up 1 to %d: usleep(0) every %d\n", LOOP, c);
for (i = 1; i <= LOOP; i++) {
sum += i;
if (!(i % c)) usleep(0);
}
printf("sleep %d times: sum = %ld\n", LOOP/c, sum);
}
-------------------------------------------------
If I make and execute this one, ...
-------------------------------------------------
[[email protected] ~]# time ./a.out
sum up 1 to 300000000: usleep(0) every 300000000
sleep 1 times: sum = 45000000150000000
real 0m11.850s
user 0m11.847s
sys 0m0.002s
-------------------------------------------------
millions loop take about 12 sec on my system.
Then, let insert some pause in the loop by usleep(0) ...
-------------------------------------------------
# pause every 1 million
[[email protected] ~]# time ./a.out 1000000
sum up 1 to 300000000: usleep(0) every 1000000
sleep 300 times: sum = 45000000150000000
real 0m12.089s
user 0m11.701s # nothing peculiar
sys 0m0.001s
-------------------------------------------------
# pause every 100 thousands
[[email protected] ~]# time ./a.out 100000
sum up 1 to 300000000: usleep(0) every 100000
sleep 3000 times: sum = 45000000150000000
real 0m15.002s
user 0m9.001s # new record!
sys 0m0.003s
-------------------------------------------------
# pause every 50 thousands
[[email protected] ~]# time ./a.out 50000
sum up 1 to 300000000: usleep(0) every 50000
sleep 6000 times: sum = 45000000150000000
real 0m18.421s
user 0m6.002s # finished in the half!
sys 0m0.002s
-------------------------------------------------
# pause every 10 thousands
[[email protected] ~]# time ./a.out 10000
sum up 1 to 300000000: usleep(0) every 10000
sleep 30000 times: sum = 45000000150000000
real 0m34.977s
user 0m0.000s # done without cpu!
sys 0m0.002s
-------------------------------------------------
What a terrible paranormal phenomena?
Of course this is an intentional misuse of tick-sampling
based time accounting. So if you repeat yielding the cpu
before a timer interrupt, and getting back the cpu after
the interrupt, you can steal cpu time without being noticed
by anyone.
However, once this accurate cpu time accounting, produced
by my patches, are enabled:
-------------------------------------------------
[root@23new ~]# time ./a.out 1000000
sum up 1 to 300000000: usleep(0) every 1000000
sleep 300 times: sum = 45000000150000000
real 0m12.308s
user 0m11.803s
sys 0m0.048s
-------------------------------------------------
[root@23new ~]# time ./a.out 100000
sum up 1 to 300000000: usleep(0) every 100000
sleep 3000 times: sum = 45000000150000000
real 0m15.002s
user 0m11.803s
sys 0m0.064s
-------------------------------------------------
[root@23new ~]# time ./a.out 50000
sum up 1 to 300000000: usleep(0) every 50000
sleep 6000 times: sum = 45000000150000000
real 0m18.004s
user 0m11.803s
sys 0m0.071s
-------------------------------------------------
[root@23new ~]# time ./a.out 10000
sum up 1 to 300000000: usleep(0) every 10000
sleep 30000 times: sum = 45000000150000000
real 0m36.497s
user 0m11.808s
sys 0m0.139s
-------------------------------------------------
you cannot be time-thief anymore.
Thanks,
H.Seto
- 関連記事
-
- CentOSでvmlinuxってどうやって入手するの? (2008/01/01)
- seto_benchが再現できない件について (2008/01/01)
- CONFIG_VIRT_CPU_ACCOUNTINGまとめ (2008/01/01)
会社で近くに座っているすごい優秀な技術者がCONFIG_VIRT_CPU_ACCOUNTINGをいじっていたので、うらまやしくなってi386版でも作ろうかとほげり始める。
が、いろいろと 2.6.24-rc6 だと構造が変わっていて元々のパッチは素直に移植できないことが分かったので、いまのCPU時間統計の仕組みをちょいと調べてみた
以下はほぼ自分用の備忘録
1.VIRT_CPU_ACCOUNTINGとはなにか?
名前がよくないのだが、最近流行の仮想化とはまったく関係ない。
よーするにcpu時間情報がtick単位でしか集計できないのは今となっては荒すぎるので
tscレジスタ相当の機能を使ってもっと細かくとれるようにしましょう。と
そういう機能
2.どうやってつかうの?
netlink機能のなかのtaskstatの情報を吸い出すことで見ることができる。
サンプルが linux/Documentation/getdelays.c あたりにある
3.サポートされてるプラットフォームは?
ppcとs390(だけ)
よく、MIな部分にコードつっこめれたよね
4.ポーティング方法は?
POWERがMD層でやっている事を以下に列挙するのでそれを真似してちょ
# なお、POWERには時間を取得するレジスタが3種類あって、それぞれ意味が違う。
# それは記事末尾で補足する。
A. 移植したいアーキのKconfig にCONFIG_VIRT_CPU_ACCOUNTINGを追加
B. include/asm/cputime.h を書き換えてcputime_tの粒度をtickからPURR
の粒度に定義しなおす。
C.システムコールの入り口で以下の処理をおこなう
- PURRをとる
- get_paca()->startpurr とPURR現在値の差分をget_paca()->user_timeに加算する
- get_paca()->startpurr にPURR現在値を保存
D.システムコール出口で以下の処理を行う
- PURRをとる
- get_paca()->startpurr とPURR現在値の差分をget_paca()->system_timeに加算する
- get_paca()->startpurr にPURR現在値を保存
E.__switch_toに以下の処理を追加
account_system_vtime(current);
account_process_tick(current, 0);
calculate_steal_time();
要するに、プロセスコンテキストの切り替えの直前に今までper_cpu変数にためこんでおいた
CPU時刻を吐き出しているのである
F. account_system_vtime という関数を作る。これはirq, softirqの出入り口と
__switch_toから呼ばれる関数。
以下のように定義する
(ここのPOWERの実装は気が狂ってるとしか思えないのでS390も併記する)
- PURRとget_paca()->startpurrの差分をとる(delta)
- get_puaca()->startpurrを現在時刻で初期化
- SPURRとget_paca()->startspurrの差分をとる(deltascaled)
- get_puaca()->startspurrを現在時刻で初期化
- 割り込み中じゃなければ以下の補正
o deltascaled *= system_time / (system_time + user_time)
これは全体の時間中のsystem_time時間の%を意味する。
って、システムコールの出入り口でstartspurrを更新してないのはおかしいんとちゃうか・・
o delta += system_time
o get_paca()->system_timeを0初期化
- account_system_timeをdeltaを引数にして呼び出す
ここで、hardirq_offset引数を常に0にしているのはたぶんバグ
preempt_count()で簡単にとれるはずやろ・・・
- account_system_time_scaledをdeltascaledを引数にして呼び出す
- get_paca()->purrdelta = delta
- get_paca()->spurrdelta = deltascaled
以下、S390の場合
- CPUタイマの前回時刻との差分をsystem_timeにセット
- CPUタイマの前回時刻を現在時刻にセット
- account_system_timeを呼び出す
G. update_process_times()から呼ばれるCPU時間更新処理account_process_tick()が
MIな定義部分が #ifndef CONFIG_VIRT_CPU_ACCOUNTING
で囲まれているので、自分のアーキのMD部分に自分用の定義を作る。
- 引数user_tickは無視(CPUのレジスタでもっと細かい時間がとれるから)
- get_paca()->user_time を引数に account_user_time()を呼び出す
- get_paca()->user_time * spurrdelta / purrdelta を引数に account_user_time_scaled()を呼び出す
- get_paca()->user_time, get_paca()->spurrdelta, get_paca()->purrdeltaを0で初期化
なお、purrdelataが0でないことは以下で保障している(0割の考慮がないコードに見えたので調べた)
- hard irq の出入り口でaccount_system_vtimeが呼ばれているので、ここを通るときは
絶対purrdelta, spurrdeltaに値が入っている
- 後述する __switch_toから呼ぶときもaccount_process_tickの直前にaccount_system_vtimeを呼んでいる
<補足 POWERの時間関係のレジスタの違いについて>
TB: 現実世界の時間と同じように進む。チップセットのタイマーでいいじゃんという気がしなくもない
PURR: SMT時に自分がactive stateだったcycleのみカウンタがすすむ周波数カウンタ
haltしてもう一方のスレッドに処理をゆずっているときはカウンタは増えない
SPURR: PURR * (feffective/fnominal) * (1 - cyclesthrottled/cyclestotal)
などというよく分からない数式で定義されているカウンタ。ようするに省電力モードで
周波数が落ちたときはそれに応じて進み方が遅くなる。と
ちなみにaccount_user_time_scaled()のscaledはSPURRがScaled PURRの略だからだ。ばかすぎる
なので、PURRだと省エネモードのときに実際の動いたクロックよりもすんげー速く進んでしまって
悲しい思いをすることになる。
困ったことにx86はtscの定義があいまいなので、省エネモードのときの動作はimplementation defined
っぽい気がする
<補足2 結局scaledtimeとstealedtimeってなんなん?>
scaledtime:省電力モードで周波数が半分になっているときは半分だけカウントアップしてくれる
steal: SMTの相方のせいで動けなかった時間
(これが計測できるってことはPOWER5の公称SMTは実装としてはVMTってことだよね:)
急いでいたので、乱文、失礼。
急いでいたので! ランキング!
- 関連記事
-
- seto_benchが再現できない件について (2008/01/01)
- CONFIG_VIRT_CPU_ACCOUNTINGまとめ (2008/01/01)
- mem notification v4 候補 (2007/12/31)