Feature #2447

reduce GC pressure by symbol table without String instance

Added by Yusuke Endoh over 4 years ago. Updated over 1 year ago.

[ruby-dev:39846]
Status:Assigned
Priority:Low
Assignee:Yusuke Endoh
Category:core
Target version:next minor

Description

=begin
遠藤です。

現在のシンボルテーブルは、シンボルごとに String のインスタンスを
割り当ててシンボル名を管理しますが、そのせいで GC の効率が落ちて
いると思います。

String ではなく ALLOC で直接確保した領域で管理するパッチを書きま
した。極端な例ではこのくらい早くなります。

# パッチ前
$ time ./ruby.org -e '10000.times { GC.start }; p ObjectSpace.count_objects[:T_STRING]'
1778

real 0m3.766s
user 0m3.764s
sys 0m0.004s

# パッチ後
$ time ./ruby.new -e '10000.times { GC.start }; p ObjectSpace.count_objects[:T_STRING]'
433

real 0m2.880s
user 0m2.876s
sys 0m0.004s

benchmark 結果は最後にあります。多くのものはほぼ変わらないか速く
なっていると思います。
so_meteor_contest は有意に速度低下しますが (再現性あり) 、理由は
よくわかりません。vm3_thread_mutex は実行する度に実行時間が大きく
変わっていた (3 秒以下から 30 秒超) ので、参考になりませんでした。

どなたか追試してくださると助かります。私の環境で make test-all は
通っています。

1.89s (2.57%): vm2_eval 73.65->71.76
1.88s (2.44%): so_fannkuch 77.14->75.25
1.86s (8.08%): so_partial_sums 23.04->21.18
1.73s (7.20%): so_mandelbrot 23.98->22.26
1.43s (8.68%): so_spectralnorm 16.43->15.00
1.02s (6.19%): so_nbody 16.49->15.47
0.99s (1.13%): app_pentomino 87.50->86.51
0.82s (6.67%): vm1_block 12.23->11.41
0.76s (5.28%): so_nsieve_bits 14.37->13.61
0.51s (15.68%): vm3_gc 3.25->2.74
0.34s (3.16%): so_fasta 10.69->10.35
0.23s (5.13%): so_exception 4.52->4.29
0.22s (3.01%): loop_for 7.45->7.22
0.19s (9.06%): app_raise 2.10->1.91
0.18s (4.67%): so_object 3.88->3.70
0.12s (1.77%): loop_times 6.54->6.42
0.11s (8.49%): so_random 1.31->1.20
0.09s (2.44%): app_uri 3.88->3.78
0.09s (1.07%): vm1_simplereturn 8.35->8.26
0.07s (4.13%): app_strconcat 1.64->1.57
0.06s (0.80%): vm2_mutex 7.33->7.27
0.06s (2.94%): app_erb 1.95->1.89
0.05s (0.59%): vm2_method 8.94->8.89
0.04s (1.04%): vm2_array 3.63->3.59
0.04s (0.97%): vm1_rescue 3.80->3.76
0.03s (0.56%): so_nested_loop 5.88->5.85
0.03s (0.75%): loop_generator 3.83->3.80
0.03s (0.51%): so_pidigits 5.38->5.35
0.03s (2.87%): io_file_read 0.95->0.93
0.03s (0.74%): vm2_proc 3.51->3.48
0.02s (0.65%): vm1_ensure 3.82->3.79
0.02s (1.45%): vm2_poly_method_ov 1.64->1.61
0.02s (0.74%): vm2_zsuper 2.88->2.86
0.02s (2.50%): app_mandelbrot 0.83->0.80
0.02s (0.46%): app_tak 4.36->4.34
0.02s (1.34%): vm2_case 1.24->1.23
0.01s (1.04%): io_file_create 1.18->1.17
0.01s (0.43%): so_matrix 2.11->2.10
0.01s (0.18%): so_ackermann 3.62->3.62
0.01s (0.19%): app_fib 3.21->3.21
0.01s (1.47%): so_sieve 0.41->0.40
0.00s (0.06%): vm1_ivar 6.23->6.22
0.00s (0.03%): so_concatenate 1.91->1.91
0.00s (0.05%): app_factorial 0.66->0.66
0.00s (0.00%): vm1_neq 6.22->6.22
-0.00s (-0.03%): vm2_send 2.02->2.02
-0.00s (-0.41%): app_answer 0.24->0.25
-0.00s (-1.53%): so_reverse_complement 0.09->0.09
-0.00s (-1.96%): so_k_nucleotide 0.07->0.07
-0.00s (-0.38%): io_file_write 0.44->0.44
-0.00s (-0.11%): loop_whileloop 3.38->3.39
-0.00s (-0.13%): app_tarai 3.51->3.51
-0.01s (-0.64%): so_count_words 1.09->1.10
-0.01s (-0.68%): so_lists 1.68->1.69
-0.02s (-2.50%): loop_whileloop2 0.67->0.68
-0.02s (-1.04%): vm2_unif1 1.76->1.78
-0.02s (-1.12%): so_binary_trees 1.81->1.83
-0.03s (-1.10%): vm2_super 2.75->2.78
-0.03s (-0.56%): vm1_const 5.80->5.83
-0.05s (-0.70%): vm2_regexp 6.55->6.59
-0.05s (-0.51%): vm3_thread_create_join 10.49->10.55
-0.06s (-1.18%): vm1_swap 5.18->5.24
-0.11s (-2.21%): vm1_not 4.91->5.02
-0.14s (-1.19%): vm2_poly_method 11.83->11.97
-0.14s (-2.11%): vm1_length 6.64->6.78
-0.15s (-2.33%): vm1_ivar_set 6.57->6.72
-0.18s (-2.42%): so_array 7.40->7.58
-0.31s (-2.23%): so_nsieve 13.79->14.10
-2.22s (-8.38%): so_meteor_contest 26.50->28.72
-26.20s (-177.28%): vm3_thread_mutex 14.78->40.99

--
Yusuke Endoh mame@tsg.ne.jp
=end

symbol_table_without_string.patch Magnifier (8.03 KB) Yusuke Endoh, 12/06/2009 11:24 PM

History

#1 Updated by Yukihiro Matsumoto over 4 years ago

=begin
まつもと ゆきひろです

In message "Re: [Bug #2447] reduce GC pressure by symbol table without String instance"
on Sun, 6 Dec 2009 23:24:59 +0900, Yusuke Endoh redmine@ruby-lang.org writes:

|現在のシンボルテーブルは、シンボルごとに String のインスタンスを
|割り当ててシンボル名を管理しますが、そのせいで GC の効率が落ちて
|いると思います。
|
|String ではなく ALLOC で直接確保した領域で管理するパッチを書きま
|した。極端な例ではこのくらい早くなります。

確かに。実はSymbolをGCの対象としようとする伏線で現状のように
なっているのですが、思ったより難しくて放置してます。当面、
SymbolのGCはできそうにないんだから、遠藤さんの指摘のようにす
べきなのかなあ。

=end

#2 Updated by _ wanabe over 4 years ago

=begin
ワナベと申します。

09/12/06 Yusuke Endoh redmine@ruby-lang.org:

現在のシンボルテーブルは、シンボルごとに String のインスタンスを
割り当ててシンボル名を管理しますが、そのせいで GC の効率が落ちて
いると思います。

String ではなく ALLOC で直接確保した領域で管理するパッチを書きま
した。極端な例ではこのくらい早くなります。
(中略)
どなたか追試してくださると助かります。私の環境で make test-all は
通っています。

興味がありますので試してみたところ、
少し不思議な結果になりましたので報告させていただきます。
詳細はわかりませんが、環境が貧弱であることが関係していると思われます。

生のベンチマーク結果を末尾に添付します。
そのうち大きく差があったものについて、改めて再現性を調べました。

  • 速くなったもの、再現性あり
    app_pentomino : 185 - 187 秒 => 182 - 183 秒
    so_fannkuch : 194 - 195 秒 => 191 - 192 秒
    so_mandelbrot : 56.1 - 56.3 秒 => 48.2 - 48.3 秒
    so_nbody : 39.2 - 39.5 秒 => 34.4 - 35.0 秒
    so_partial_sums : 54.3 - 54.5 秒 => 47.0 - 47.0 秒
    so_spectralnorm : 39.4 - 39.6 秒 => 35.4 - 35.5 秒
    vm1_block* : 28.5 - 29.5 秒 => 22.5 - 22.8 秒
    vm1_const* : 6.4 - 6.6 秒 => 5.5 - 5.5 秒
    vm1_not* : 5.6 - 5.8 秒 => 4.1 - 4.2 秒
    vm3_gc : 10.4 - 10.5 秒 => 9.0 - 9.0 秒

  • 遅くなったもの、再現性あり
    loop_whileloop2 : 17.0 - 17.5 秒 => 18.0 - 18.5 秒
    so_ackermann : 8.6 - 8.7 秒 => 8.7 - 8.9 秒
    so_exception : 11.8 - 12.2 秒 => 12.8 - 13.4 秒
    so_meteor_contest : 46.4 - 48.8 秒 => 50.4 - 51.2 秒
    so_reverse_complement : 388 - 389 秒 => 391 - 392 秒
    vm2_eval* : 195 - 198 秒 => 206 - 207 秒

  • 生データでは変化があったが、再現性のないもの
    app_tak : パッチ前後ともに 10.5 - 11.2 秒
    io_file_read : パッチ前後ともに 39 - 42 秒
    loop_generator : パッチ前後ともに 5.6 - 6.2 秒
    loop_times : パッチ前後ともに 14.1 - 14.5 秒
    so_count_words : パッチ前後ともに 2 - 5 秒
    so_array : パッチ前後ともに 13 - 19 秒
    so_sieve : パッチ前後ともに 1.3 - 4.2 秒

    benchmark results:
    name ruby 1.9.2dev (2009-12-06 trunk 26029) [i386-mingw32] ruby
    1.9.2dev (2009-12-06 trunk 26029) [i386-mingw32]
    app_answer 0.766 0.797
    app_erb 4.484 4.422
    app_factorial 2.500 2.641
    app_fib 7.797 7.984
    app_mandelbrot 2.125 2.172
    app_pentomino 187.578 183.078
    app_raise 5.422 5.438
    app_strconcat 3.313 3.172
    app_tak 10.547 11.141
    app_tarai 9.203 9.313
    app_uri 8.828 8.391
    io_file_create 33.641 32.641
    io_file_read 39.219 42.203
    io_file_write 28.719 28.578
    loop_for 15.875 15.875
    loop_generator 5.719 6.125
    loop_times 13.984 14.328
    loop_whileloop 8.125 8.156
    loop_whileloop2 1.734 1.844
    so_ackermann 8.672 8.781
    so_array 19.031 13.938
    so_binary_trees 3.906 4.016
    so_concatenate 3.719 3.813
    so_count_words 5.734 6.844
    so_exception 12.047 13.203
    so_fannkuch 195.047 191.688
    so_fasta 25.000 24.891
    so_k_nucleotide 16.469 16.797
    so_lists 3.453 3.406
    so_mandelbrot 56.344 48.313
    so_matrix 4.172 4.266
    so_meteor_contest 46.438 50.484
    so_nbody 39.297 34.922
    so_nested_loop 11.859 12.031
    so_nsieve 28.922 29.125
    so_nsieve_bits 27.938 27.281
    so_object 9.063 9.656
    so_partial_sums 54.563 47.047
    so_pidigits 17.578 17.594
    so_random 3.609 3.328
    so_reverse_complement 387.969 392.344
    so_sieve 2.234 1.531
    so_spectralnorm 39.375 35.422
    vm1_block* 29.516 22.875
    vm1_const* 6.438 5.547
    vm1_ensure* 2.344 2.250
    vm1_ivar* 7.844 7.547
    vm1_ivar_set* 7.031 7.000
    vm1_length* 8.797 8.594
    vm1_neq* 6.547 6.922
    vm1_not* 5.688 4.172
    vm1_rescue* 2.328 2.250
    vm1_simplereturn* 13.078 12.797
    vm1_swap* 4.375 4.328
    vm2_array* 15.063 15.016
    vm2_case* 1.844 1.656
    vm2_eval* 195.141 206.078
    vm2_method* 19.266 19.016
    vm2_mutex* 12.469 12.422
    vm2_poly_method* 24.109 24.188
    vm2_poly_method_ov* 2.344 2.328
    vm2_proc* 5.859 5.844
    vm2_regexp* 9.953 9.438
    vm2_send* 3.156 2.891
    vm2_super* 4.781 4.641
    vm2_unif1* 2.813 2.625
    vm2_zsuper* 5.500 5.406
    vm3_gc 10.531 9.031
    vm3_thread_create_join 27.234 27.828
    vm3_thread_mutex 3.000 3.188

    ワナベ

=end

#3 Updated by Yusuke Endoh over 4 years ago

=begin
遠藤です。

2009年12月8日18:37 wanabe s.wanabe@gmail.com:

どなたか追試してくださると助かります。私の環境で make test-all は
通っています。

興味がありますので試してみたところ、
少し不思議な結果になりましたので報告させていただきます。
詳細はわかりませんが、環境が貧弱であることが関係していると思われます。

生のベンチマーク結果を末尾に添付します。
そのうち大きく差があったものについて、改めて再現性を調べました。

とても詳しい追試、ありがとうございます。

  • 速くなったもの、再現性あり app_pentomino : 185 - 187 秒 => 182 - 183 秒 so_fannkuch : 194 - 195 秒 => 191 - 192 秒 so_mandelbrot : 56.1 - 56.3 秒 => 48.2 - 48.3 秒 so_nbody : 39.2 - 39.5 秒 => 34.4 - 35.0 秒 so_partial_sums : 54.3 - 54.5 秒 => 47.0 - 47.0 秒 so_spectralnorm : 39.4 - 39.6 秒 => 35.4 - 35.5 秒 vm1_block* : 28.5 - 29.5 秒 => 22.5 - 22.8 秒 vm1_const* : 6.4 - 6.6 秒 => 5.5 - 5.5 秒 vm1_not* : 5.6 - 5.8 秒 => 4.1 - 4.2 秒 vm3_gc : 10.4 - 10.5 秒 => 9.0 - 9.0 秒

それぞれ 2% 、2% 、14% 、12% 、14% 、10% 、21% 、15% 、27% 、13%
くらいの高速化ですね。

  • 遅くなったもの、再現性あり loop_whileloop2 : 17.0 - 17.5 秒 => 18.0 - 18.5 秒 so_ackermann : 8.6 - 8.7 秒 => 8.7 - 8.9 秒 so_exception : 11.8 - 12.2 秒 => 12.8 - 13.4 秒 so_meteor_contest : 46.4 - 48.8 秒 => 50.4 - 51.2 秒 so_reverse_complement : 388 - 389 秒 => 391 - 392 秒 vm2_eval* : 195 - 198 秒 => 206 - 207 秒

-6% 、-2% 、-9% 、-7% 、-1% 、-5% くらいですね。

総じて言えば、速くなっていると言えるのではないかと思います。
どうでしょうか。

--
Yusuke ENDOH mame@tsg.ne.jp

=end

#4 Updated by Yusuke Endoh about 4 years ago

=begin
遠藤です。

明らかに feature request なので移動します。

--
Yusuke Endoh mame@tsg.ne.jp
=end

#5 Updated by Shyouhei Urabe almost 4 years ago

  • Status changed from Open to Assigned

=begin

=end

#6 Updated by Koichi Sasada about 2 years ago

  • Description updated (diff)

あれ,これ私ですか.
ええと,今度やります.これは,big feature じゃないから遅くてもいいよね.

#7 Updated by Yusuke Endoh about 2 years ago

明らかに feature request なので移動します。

自分へのツッコミですが、「明らかに bug ではない」が正確ですね。
こういう最適化みたいに、ユーザが直接観察できない改善は、feature request deadline 後でもいいと思います。

ただ、(時期は決めてなかったと思いますが) code freeze 後ではダメだし、branch を切った後でも面倒になると思うので、なるべく早めにやってください。

Yusuke Endoh mame@tsg.ne.jp

#8 Updated by Koichi Sasada over 1 year ago

  • Assignee changed from Koichi Sasada to Yusuke Endoh

すみません,「やります」と書いておきながら,全然覚えてないんですが,
私はとくに反論ないので(テストが通るなら),遠藤さん入れちゃいませんか?

#9 Updated by Yusuke Endoh over 1 year ago

  • Priority changed from Normal to Low

うーん、他の作業がすべて終わったあとで気力があればやります。ないかも

Yusuke Endoh mame@tsg.ne.jp

#10 Updated by Yusuke Endoh over 1 year ago

  • Target version changed from 2.0.0 to next minor

他にやってくれる人がいなければ next minor 送りで。

Yusuke Endoh mame@tsg.ne.jp

Also available in: Atom PDF