ブログ練習。随時書き換えを想定。 Gist なら履歴が残るのがいいんではないかなと。
https://twitter.com/__gfx__/status/915772496778952706 という tweet がありました。
Ruby で、def foo(&block) などとして受け取って block.call すると、yield で呼び出すよりも遅い、とのこと。
さてどのくらいか。
| FROM ubuntu:16.04 | |
| RUN apt-get update | |
| RUN apt-get install -y git | |
| RUN git clone https://github.com/rubyomr-preview/ruby.git --branch ruby_2_2_omr --recursive | |
| # for ruby | |
| RUN apt-get install -y autoconf ruby build-essential bison | |
| # for omr | |
| RUN apt-get install -y libnuma-dev |
| $ make miniruby && ln -fs $PWD/miniruby /tmp/miniruby && printf "b compile.c:$(sed -n "/int orig_sp = sp;/=" ../compile.c)\nr\ncall dump_disasm_list(FIRST_ELEMENT(anchor))\nq"|gdb -x - --args /tmp/miniruby g.rb | |
| CC = gcc | |
| LD = ld | |
| LDSHARED = gcc -shared | |
| CFLAGS = -O0 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -Wsuggest-attribute=noreturn -Wsuggest-attribute=format -Wno-maybe-uninitialized -std=gnu99 | |
| XCFLAGS = -fstack-protector -fno-strict-overflow -fvisibility=hidden -fexcess-precision=standard -DRUBY_EXPORT -fPIE | |
| CPPFLAGS = -I. -I.ext/include/x86_64-linux -I../include -I.. -I../enc/unicode/9.0.0 | |
| DLDFLAGS = -Wl,--compress-debug-sections=zlib -fstack-p |
ブログ練習。随時書き換えを想定。 Gist なら履歴が残るのがいいんではないかなと。
https://twitter.com/__gfx__/status/915772496778952706 という tweet がありました。
Ruby で、def foo(&block) などとして受け取って block.call すると、yield で呼び出すよりも遅い、とのこと。
さてどのくらいか。
YARV-MJIT のデバッグをしながらその過程を文章にしたらどうなるか、という文です。 Advent Calendar とかどこかに書こうかと思っていたんですがだいたいどこも埋まっていたので、そういうのとは無関係に書いていきます。
CRuby の JIT の一実装で、https://github.com/k0kubun/yarv-mjit で k0kubun さんという方が開発されています。
https://speakerdeck.com/k0kubun/rails-developers-meetup-2017
$ for branch in yarv-mjit/master yarv-mjit/catch-break; do git checkout $branch && make -j4 REVISION_FORCE=PHONY ./.revision.time install-nodoc >/dev/null 2>&1 && (cd ../optcarrot; ruby -v; for i in `seq 1 1 10`; do ruby -j bin/optcarrot --benchmark examples/Lan_Master.nes|sed -ne "s/^fps: \(.*\)/\1/p"; done|ruby -e 'fps_list = []; while gets; fps_list << $_.to_f; puts "%0.2f = (%s) / %d" % [fps_list.sum / fps_list.length, fps_list.map{|fps| "%0.2f" % fps }.join(" + "), fps_list.length]; end'); done
Already on 'yarv-mjit/master'
Your branch is up-to-date with 'k0kubun/yarv-mjit/master'.
ruby 2.5.0dev (2017-12-17 yarv-mjit/master 61304) [x86_64-linux]
last_commit=mjit.c: don't call getenv every time
55.99 = (55.99) / 1
52.10 = (55.99 + 48.20) / 2
54.03 = (55.99 + 48.20 + 57.90) / 3
54.46 = (55.99 + 48.20 + 57.90 + 55.75) / 4| require "fiddle/import" | |
| class RubyVM::InstructionSequence | |
| module InternalFunction | |
| extend Fiddle::Importer | |
| dlload Fiddle::Handle::DEFAULT | |
| if Fiddle::SIZEOF_LONG == Fiddle::SIZEOF_VOIDP | |
| typealias "VALUE", "unsigned long" | |
| elsif Fiddle::SIZEOF_LONG_LONG == Fiddle::SIZEOF_VOIDP | |
| typealias "VALUE", "unsigned long long" |
| $ RAILS_ENV=production ruby -W0 -S bundle exec rake bench RBENV="trunk trunk,--jit,--jit-min-calls=3000:TRAINING_NUM=3000:WAIT_SEC=100 trunk+mjit-same-so,--jit,--jit-min-calls=3000:TRAINING_NUM=3000:WAIT_SEC=100" DURATION=10 | |
| Booting: production | |
| Endpoint: "/" | |
| Warming up -------------------------------------- | |
| bench 1.066k i/s | |
| Calculating ------------------------------------- | |
| trunk trunk,--jit,--jit-min-calls=3000,TRAINING_NUM=3000,WAIT_SEC=100 trunk+mjit-same-so,--jit,--jit-min-calls=3000,TRAINING_NUM=3000,WAIT_SEC=100 | |
| bench 1.031k 594.824 795.382 i/s - 10.663k times in 10.343410s 17.926304s 13.406132s | |
| Comparison: |