ruby-trunk-changes 2019-07-18

今日は Fiber pool の実装の追加がありました。チューニングや解放戦略の実験とかまだしばらくありそうですが、Fiber の生成が高速になりそうです。

[416ead4cda] Yusuke Endoh 2019-07-16 23:24:25 UTC

compile.c で式の値を使ってないところに NO_CHECK() マクロを使って Coverity Scan の警告を抑制するのをもう一箇所追加しています。

[bdec1ad9a9] git 2019-07-17 14:42:21 UTC

416ead4cdaf849fe1f3dcda26d6ba04c80e36746 のインデントのタブを空白に展開。

[9b28eefeb2] Samuel Williams 2019-07-17 23:13:49 UTC

benchmark/ に Fiber を大量に作って保持するベンチマークを追加しています。 Fiber が大量にある状態での GC が 88449100bc6d23a00dbf3addb97665f4f606f2b8 で遅くなってたのでとりあえずそのベンチマーク追加みたいですね。 sweep rest を抑制して遅くなるっていうのもちょっと不思議ですね。 [ruby-core:93820] [Bug #16009]

[97808e29cd] git 2019-07-17 23:15:46 UTC

version.h の日付更新

[1b82c877df] Samuel Williams 2019-06-01 05:48:25 UTC

FIBER_USE_NATIVE というマクロは廃止して、無条件で有効なものとして preprocessor の分岐を消しています。

[14cf95cff3] Samuel Williams 2019-06-02 00:49:58 UTC

Fiber pool を導入して Fiber 用の VM/Machine Stack の領域をまとめて確保するようにしています。しかも複数の Fiber 用の領域を一度にフラットに確保して切り分けて使うようにしているようです。Fiber の生成を高速化するためみたいですけど、ちょっとだけ使う時のメモリ量のオーバーヘッドが大きそう……。

[8779382da4] Samuel Williams 2019-06-19 12:13:49 UTC

USE_THREAD_DATA_RECYCLE が真の時の Thread と Fiber で VM スタックを使いまわす機構は Fiber pool 導入で不要になったので削除しています。

[91aae651bf] Samuel Williams 2019-06-27 06:59:25 UTC

coroutine/copy/Context.[ch] というマシンスタックをメモリコピーによって退避する実装を追加して、各種アーキテクチャ向けの実装が使えない時にこの実装を利用するようにしています。

[7291fef55c] Samuel Williams 2019-06-29 01:07:07 UTC

91aae651bf90be46773a246e4c46b9e221353fbd でこれまでのアーキテクチャごとの Coroutine 実装が使えないケースもカバーする C 実装の Coroutine が作られたので configure の Fiber 実装の選択部分をちょっと(?)変更しています。変数名の改名が大部分であとは Coroutine 実装がない時の処理のかわりに copy を使うようになったのでちょっとシンプルに書けるようになった、というのと --with-coroutine というオプションで copy/ucontext など configure 時に指定できるようにしています。

[b8242bce23] Samuel Williams 2019-06-29 12:21:19 UTC

.travis.yml でビルド条件に copy タイプの Coroutine 実装を使うビルドを追加しています。 --with-coroutine=ucontext をつけて configure するタイプも追加しているけど結局 ucontext も残ってるのか。よくわからん。

[47c0cab248] Samuel Williams 2019-07-01 04:24:39 UTC

NEWS ファイルに Fiber pool の追加と configure の --with-coroutine オプションについて追記しています。

[77f3319071] Samuel Williams 2019-07-11 07:17:34 UTC

Fiber bool の VM/Machine スタックの領域を解放する時に madvise(2) を使ってすぐに実際にメモリを解放してシステム側に返すようにヒントを指定するようにしています。

[8ac9a7be0f] Samuel Williams 2019-07-12 01:42:34 UTC

Fiber pool のスタック確保の実装で一度に確保した領域内で使用中/未使用の領域を管理するリストを双方向リストにしています。またコミットログみるとこっちが主眼らしいけど、32bit システム向けに一度に確保するサイズの制限を 1024 -> 32 とかなり小さくしています。

[4d60a5820a] Samuel Williams 2019-07-16 00:49:14 UTC

8ac9a7be0fea95d9fc17cce53c0d18d70cc8d091 で追加した Fiber pool のスタック領域管理のリストを双方向にして解放時の優先度を変えたのは FIBER_POOL_ALLOCATION_FREE というマクロが定義された時だけ使うようにしています。実験中かな。

[385ea910fc] Samuel Williams 2019-07-16 04:00:35 UTC

struct fiber_pool 構造体に free_stacks というメンバーを追加してこのメンバーをみて fiber_pool_stack_free() を呼ぶかどうかを制御するようにしている、のですが初期化時に 1 にしてその後変更しているところがないので実質変化がないような…。

[001f187ed6] Samuel Williams 2019-07-16 04:11:55 UTC

8ac9a7be0fea95d9fc17cce53c0d18d70cc8d091 で 32bit 環境での Fiber pool のまとめて確保するスタック数の制限を sizeof(void*) で決めてたのを Coroutine の実装毎に COROUTINE_LIMITED_ADDRESS_SPACE というマクロを定義したりしなかったりして決めるようにしています。また初期値も変えるようにしているうえ大きく使える環境での上限は 4096 まで増やしてます。そんなに確保して大丈夫なのかな…。

[56fcf98849] Samuel Williams 2019-07-16 04:35:27 UTC

ベンチマーク benchmark/vm2_fiber_count.yml のコメントに Linux では sysctl で vm.max_map_count を増やさないといけないよとメモを追加しています。

[311007bf40] Samuel Williams 2019-07-16 04:35:55 UTC

385ea910fc28f0e46c72669a260e44d4f3f37d9e で導入した struct fiber_pool::free_stacks というメンバーですが、通常書き変えられないので挙動に変化がなかったのですが環境変数 RUBY_SHARED_FIBER_POOL_FREE_STACKS にセットされていた文字列を atoi(3) で変換して shared_fiber_pool.free_stacks にはセットするようにしています。つまり 0 にセットすると Fiber が全て使われなくなっても最初の Fiber pool のスタック領域は解放せずに置いておくことになるんですかね、たぶん。

[38e3c65a33] Samuel Williams 2019-07-18 07:02:16 UTC

Fiber pool のスタック領域をまとめて確保する fiber_pool_expand() でヘッダ部分である struct fiber_pool_allocation のメモリ確保の前にスタックとして使うメモリ領域の確保をする、ようにしているんだけど、これだと構造体のほうの RB_ALLOC() で例外発生した場合にリークするんじゃないかな? また 001f187ed6539f320421d8893d2f3c8f584cc3a5 でさらっと 4096 に増やしてた、まとめて確保するスタック数の上限をまた 1024 に戻しています。

[78bc6cd8df] git 2019-07-18 08:55:22 UTC

14cf95cff35612c6238790ad2f605530f69e9a44 の行末の空白除去。

[9790b778a3] Samuel Williams 2019-07-18 12:33:03 UTC

14cf95cff35612c6238790ad2f605530f69e9a44 の fiber_stack_release() で ec->cfp を NULL クリアし忘れてたのを修正しています。

[d40d8b3caf] Koichi Sasada 2019-07-18 13:59:44 UTC

Continuation の mark 関数で cont->saved_ec を mark する前にその cfp が NULL になってないかチェックするように修正しています。