同時に複数のスレッドが動作可能になる「Ruby 1.9.3のGVLにHTMを用いるパッチ」を当てて rbenv / ruby-build でインストール

##'14/6/30 追記：
別途、公開されたビルド方法で Ruby 1.9.3-p547 をインストールしましたが、やはり HTM が働きませんでした。理由は記事の末尾に…orz
#おことわり
HTM がちゃんと動くか確認してませんし、 HTM 動作時に性能の差が出ているのかについても確認してません。インストールしてエラーが出なかった、というだけです。
もし動作確認頂けましたらコメントお願いします。また誤りがありましたらお気軽にコメントにてご指摘ください。
#オプション指定について
`CONFIGURE_OPTS` の設定のうち、この HTM に必要なオプション指定は `--enable-htm-gvl` のみです。その他オプションが不要であれば削除してください。
##当方の動作環境
MacBook Pro with Retina 13" (Late 2013) 2.4 GHz Intel Core i5

#「RubyのGVLにHTMを用いるパッチ」の解説
オリジナルから引用します。
>##これは何？
オリジナルのRuby VMの実装(CRuby, MRI)は大域VMロック(Giant VM Lock; GVL)を用いています。GVLのおかげでVMと拡張ライブラリの開発者は並列プログラミングについて考える必要が無く実装が容易になります。しかしそのせいで、Rubyでマルチスレッドプログラムを書いても同時に一つのスレッドしか実行されないという性能上の問題がありました。一方、近年のCPUにはハードウェアトランザクショナルメモリ(Hardware Transactional Memory; HTM)と呼ばれる新しい機能が実装されています。HTMをロックの代わりに用いると、開発者は並列プログラミングについてほとんど考える必要が無いまま、同時に複数のスレッドが動作可能になり性能問題が解決する、と言われています。我々はRuby VMのGVLをHTMで置き換えた実験を行い、PPoPP 2014で発表しました。
このページでは実験で用いたコードをRuby VMに対するパッチとして公開しています。
##実行方法
ビルドされたRubyのバイナリはデフォルトでGVLにHTMを用います。実行するにはIBM POWER HTMかIntel TSXを実装したCPUが必要です。パッチはAIX/POWER8とLinux/Intel Haswellプロセッサ上でテストしています。
[Rei Odaira - RubyのGVLにHTMを用いるパッチ](http://researcher.watson.ibm.com/researcher/view_person_subpage.php?id=5511)

#ruby-buildでインストール
Ruby 1.9.3-p547 の HTM 版のインストール先を `$HOME/bin/ruby_htm` と指定してインストールしています。

```bash
$ curl -sSL -o $HOME/bin/build/ruby_htm_gvl-1.9.3-p547.patch http://researcher.watson.ibm.com/researcher/files/jp-ODAIRA/ruby_htm_gvl-1.9.3-p547.patch | env TMPDIR="$HOME/bin" RUBY_BUILD_BUILD_PATH="$HOME/bin/build" CONFIGURE_OPTS="--enable-htm-gvl --enable-shared --with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl`" ruby-build -f --patch 1.9.3-p547 $HOME/bin/ruby_htm
```
インストール後は

```bash
$ ~/bin/ruby_htm/bin/ruby -v
ruby 1.9.3p547 (2014-05-14 revision 45962) [x86_64-darwin13.2.0]
```
という動作だけ確認しました。適当に PATH を通すなりなんなりしてください。

#rbenvでインストール
Ruby 1.9.3-p547 の HTM 版がいつもの rbenv 管理ディレクトリ `$HOME/.rbenv/versions` 以下にインストールされます。
なお、予め 1.9.3-p547 をインストールしている場合には `$HOME/.rbenv/versions/1.9.3-p547` をコピーして `$HOME/.rbenv/versions/1.9.3-p547.bak` を作っておくと、`rbenv global` が効く…かもしれません（詳細未確認ですが動きそうな気配）。

```bash
$ curl -sSL -o $HOME/tmp/build/ruby_htm_gvl-1.9.3-p547.patch http://researcher.watson.ibm.com/researcher/files/jp-ODAIRA/ruby_htm_gvl-1.9.3-p547.patch | env TMPDIR="$HOME/tmp/" RUBY_BUILD_BUILD_PATH="$HOME/tmp/build" CONFIGURE_OPTS="--enable-htm-gvl --enable-shared --with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl`" rbenv install -f --patch 1.9.3-p547
```
やはりこちらもインストール後は

```bash
$ rbenv global 1.9.3-p547
$ ruby -v
ruby 1.9.3p547 (2014-05-14 revision 45962) [x86_64-darwin13.2.0]
```
という動作確認のみしました。
ちなみに `1.9.3-p547.bak` にバックアップした元の Ruby 1.9.3-p547 は

```bash
$ rbenv global 1.9.3-p547.bak 
$ ruby -v
ruby 1.9.3p547 (2014-05-14 revision 45962) [x86_64-darwin13.2.0]
```
という動作確認のみしております。

#スクリプト解説
パッチファイルを `curl` で指定したディレクトリに保存して、それと同じディレクトリで Ruby インストールのテンポラリファイルなどを置いて作業させています。 `TMPDIR` とか `RUBY_BUILD_BUILD_PATH` とかですね。

>##Special environment variables

>* `TMPDIR` sets the location where ruby-build stores temporary files.
* `RUBY_BUILD_BUILD_PATH` sets the location in which sources are downloaded and built. By default, this is a subdirectory of TMPDIR.

>[sstephenson/ruby-build](https://github.com/sstephenson/ruby-build#special-environment-variables)

#最後に
テキトーに試して楽しんでください。
そしてインストールに関してド素人の私にいろいろ教えてくださいm(_ _)m
path が `$HOME/bin` で適切なのかさえ分かってませんorz

#'14/6/30追記：意外なオチ
どうやら HTM が働いていないようです…。
以下のスクリプトで複数のスレッドを並列動作させているつもりなのですが、 1CPU でしか動かない。

```ruby
#!/usr/bin/env ruby

require 'benchmark'

l = ARGV[0] ? ARGV[0].to_i : 120000000

Benchmark.bm(10) do |x|
  [1, 2, 4, 8, 16, 32].each do |t|
    x.report("multiply #{t}") {
      ths = []
      t.times do
        ths << Thread.new do 
          n = 2
          (l / t).times do 
            if n == 1073741824
              n = 2
            else
              n *= 2
            end
          end
        end
      end
      ths.each {|th| th.join}
    }
  end
end
```

```bash
$ ruby mc.rb 
                 user     system      total        real
multiply 1  10.050000   0.010000  10.060000 ( 10.067056)
multiply 2  10.280000   0.010000  10.290000 ( 10.286738)
multiply 4  10.440000   0.010000  10.450000 ( 10.452348)
multiply 8  10.180000   0.010000  10.190000 ( 10.185302)
multiply 16 10.340000   0.010000  10.350000 ( 10.363816)
multiply 32 10.250000   0.010000  10.260000 ( 10.255911)
```

しかも

>マルチスレッドプログラムでも常にGVLを用いたい場合は実行時オプションとして--disable-htmを指定してください。
>`ruby --disable-htm your_app.rb`
と書いてあるので試しにオプションを付けてみたら

```
$ ruby --disable-htm mc.rb
ruby: warning: unknown argument for --disable: `htm'
```
と言われてしまうし…。

##なんと CPU が対応してなかったorz
>The MacBook Pro "Core i5" 2.4 13-Inch (Late 2013 Retina Display) features a 22 nm "Haswell" 2.4 GHz Intel "Core i5" processor (4258U), with dual independent processor "cores" on a single silicon chip...
[MacBook Pro "Core i5" 2.4 13" Late 2013 Specs (Retina Late 2013 13", ME864LL/A*, MacBookPro11,1, A1502, 2678) @ EveryMac.com](http://www.everymac.com/systems/apple/macbook_pro/specs/macbook-pro-core-i5-2.4-13-late-2013-retina-display-specs.html)

を確認するとCore i5 **4258U** なのですが、インテルのサイトでスペックシートを確認すると

>###Advanced Technologies
インテル® TSX-NI:	**No**
[ARK | Intel® Core™ i5-4258U Processor (3M Cache, up to 2.90 GHz)](http://ark.intel.com/ja/products/75990/Intel-Core-i5-4258U-Processor-3M-Cache-up-to-2_90-GHz)

と書かれてましたorz
新しい CPU だから TSX は入ってるだろう、という思い込みでやってしまいましたorz
##TSX対応のCPUをお持ちの方のご確認をお待ちしております
m(_ _)m