todesking
March 26, 2016
12k

# 実行時におけるJVMバイトコード最適化手法

March 26, 2016

## Transcript

5. ### 4DBMBͷ ͞·͟·ͳந৅Խػߏ w Ϋϥε w USBJUʹΑΔNJYJO w VOBQQMZʹΑΔΧελϚΠζՄೳͳύλʔϯϚο ν w

ܕΫϥε w *NQMJDJUDPOWFSTJPO w ϑΝʔετΫϥεͳؔ਺

14. ### දݱ͍ͨ͠ཁૉ w ͜ΕΒͷجຊཁૉͰදݱͰ͖ Δ w ઀ଓ w ෼഑ w ߹ྲྀ

w ϧʔϓ w 4DBMBͰͲ͏ॻ͘

16. ### "SSPXʹΑΔදݱ + z-1 val z_1 = init(0.0) val plus =

arr { case (a, b) => a + b } val out = in >>> (z_1 &&& id) >>> plus
17. ### "SSPXʹΑΔදݱ + z-1 val z_1 = init(0.0) val plus =

arr { case (a, b) => a + b } val out = in >>> (z_1 &&& id) >>> (plus *** (arr(_._1) >>> z_1)) >>> plus + z-1 (´ŋ_ŋ`)???
18. ### "SSPXه๏ w 4DBMBʹ͓͍ͯɺϞφυ͸GPS DPNQSFIFOTJPOͰॻ͚Δ w "SSPX΋γϯλΫεγϡΨʔͰॻ͖͍ͨ w )BTLFMMʹ͸"SSPX༻ͷγϯλΫεγϡΨʔͰ ͋ΔQSPDه๏͕͋Δ w

4DBMBͰ΋΍Γ͍ͨʂ΍Γ·ͨ͠ʂ w HJUIVCUPEFTLJOHBSSPX@CVJMEFSTDBMB
19. ### "SSPXʹΑΔදݱ XJUITZOUBYTVHBS + z-1 val z_1 = init(0.0) val plus

= arr { case (a, b) => a + b } val out = for { a <- z_1 -< in b <- plus -< (in, a) c <- z_1 -< a d <- plus -< (b, c) } yield d + z-1 ʋ(´ʔʆ)ϊಡΊΔಡΊΔ a b c d in

23. ### "SSPXʹΑΓ ߏஙͨ͠ ৴߸ॲཧϑϩʔͷྫ w ؙ͍ͷ͕ؔ਺ɺ ໼ҹ͕߹੒ w ӈ൒෼Ҏ্Λ ઎ΊͯΔͷ͕ جຊతͳϞ

δϡʔϧͷͻ ͱͭɺ7\$' w Ϟδϡʔϧ; ͨͭܨ͍ͩͩ ͚Ͱ͜Ε

ݴͬͯ΋ɺͪΐͬͱ͜Ε͸
25. ### ந৅Խʹ͸ϦεΫ͕͋Δ w ύϑΥʔϚϯεΦʔόϔου w ଟ͘ͷ৔߹͸ɺ࣮༻্໰୊ʹͳΒͳ͍ w ໰୊ʹͳΔ৔߹͸ɺϗοτεϙοτͷΈ࠷దԽ͢Ε ͹Α͍ w ͔͠͠ɺϗοτεϙοτ͕දݱ͍ͨ͠υϝΠϯͦͷ

΋ͷͩͬͨ৔߹͸ʁ w ந৅ԽΛࣺͯͯϕλॻ͖͢Δ͔͠ͳ͍ͷ͔

29. ### #PYJOH5VQMJOH w (FOFSJDͳؔ਺ͷҾ਺͸࣮࣭0CKFDU w ϓϦϛςΟϒܕΛ౉͍ͨ͠৔߹͸#PYJOHൃੜ • Integer.valueOf(n) w ෳ਺ͷ஋Λฦ͍ͨ͠৔߹͸5VQMFΛ࡞Δඞཁ͕͋ Δ

w ϝϞϦ֬อͷίετɺ(\$ͷίετ͕ൃੜ
30. ### 4DBMBίϯύΠϥʹΑΔ ࠷దԽ w ಛघԽ w ܕύϥϝʔλʹ@specializedΞϊςʔγϣϯΛ͚ͭΔ͜ͱͰࢦఆ w ܕύϥϝʔλ͕ϓϦϛςΟϒܕͷ৔߹ʹରͯ͠ɺઐ༻ͷϝιουΛ ੜ੒͢Δ͜ͱͰCPYJOHΛෆཁʹ w

૊Έ߹Θͤͷ਺͚ͩϝιουΫϥε͕૿͑Δͱ͍͏σϝϦοτ͋Γ w ૊Έ߹Θͤ਺ΛݮΒ͢NJOJCPYJOHͱ͍͏ख๏΋͋Δ ͨͩ͠4DBMB ຊՈʹ͸ೖͬͯͳ͠ trait Function1[ @specialized(scala.Int, scala.Long, scala.Float, scala.Double) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double) +R ] extends AnyRef { self => ྫ: scala.Function1ͷఆٛ
31. ### 4DBMBίϯύΠϥʹΑΔ ࠷దԽ w &MJNJOBUFOPOFTDBQJOHCPYFT UVQMFT BOESFGT w ίϯύΠϧ࣌ʹɺϝιου಺Ͱ׬͍݁ͯ͠Δ CPYJOHUVQMJOHΛআڈ͢Δ w

ͰೖΔΒ͍͠Ͱ͢ w ϝιουΛ·͍ͨͩ࠷దԽͰ͸ͳ͍ͷͰɺޮՌ͸͔ ͳΓݶఆతͰ͸ͱ͍͏ؾ͕͠·͢
32. ### +7.ʹΑΔ࠷దԽ w ΤεέʔϓղੳʹΑΔΠϯελϯεੜ੒আڈ w Ұൠతʹ͸4DBMBSSFQMBDFNFOUͳͲͱ͍͏ Β͍͠ w ϝιου֎ʹ࿐ग़͍ͯ͠ͳ͍ΦϒδΣΫτΛΠϯ ϥΠϯԽ w

ߴ଎ͳϝϞϦ֬อͱ(\$ॲཧ w OFX΍(\$ͷίετΛۃݶ·ͰݮΒͤ͹Ͳ͏ͱ͍ ͏͜ͱ͸ͳ͍
33. ### Ծ૝ؔ਺ݺͼग़͠ w SFDFJWFSͷΫϥεΛݩʹಈతʹݺͼઌΛม͑Δ w ༧ଌࠔ೉ͳؒ઀෼ذ͸ޮ཰͕ѱ͍ w Ծ૝Ͱͳͯ͘΋ɺؔ਺ݺͼग़͠͸ίετ͕͔͔Δ w ϓϩάϥϜͷෳࡶԽ͸࠷దԽΛ્֐͢Δ class

A { def foo: Int = 10 } class B extends A { def foo = 99 } class X { def bar(a: A) = a.foo // 10? 99? }
34. ### 4DBMBίϯύΠϥʹΑΔ ࠷దԽ w !JOMJOF w Ξϊςʔγϣϯ͕ࢦఆ͞Εͨϝιουͷݺͼग़͠ ΛίϯύΠϧ࣌ʹΠϯϥΠϯԽ w ຤ඌ࠶ؼ࠷దԽ!UBJMSFD w

຤ඌ࠶ؼݺͼग़͠Λϧʔϓʹల։
35. ### +7.ʹΑΔ࠷దԽ w *OMJOJOH w Α͘ݺͼग़͞ΕΔখ͍͞ϝιουΛ࣮ߦ࣌ʹΠϯ ϥΠϯల։͢Δ w ݺͼग़͞ΕΔϝιουͷީิ͕ݶΒΕ͍ͯΔ৔߹ɺ Ծ૝ؔ਺ݺͼग़͠ΛܕνΣοΫ ௚઀ݺͼग़͠ʹม

׵ w +*5ίϯύΠϥͷৄࡉʹؔ͢Δࢿྉ͸๡͍͠ͷͰɺ ΘΓͱṖʹแ·Ε͍ͯ·͢ 0QFO+%,ͷίʔυΛ ͕Μ͹ͬͯಡΊ͹͍͍ΜͰ͕͢ʜʜ

39. ### ؔ਺߹੒ͷ ύϑΥʔϚϯε w YTMPXFS standardF ௨ৗͷؔ਺߹੒ 4515.900 ± 154.250 baseline

߹੒ͤͣ௚઀ݺͿ 21772.108 ± 154.944 val f1: Int => Int = { x => x + 1 } val f2: Int => Double = { x => x + 10.0 } val f3: Double => Int = { x => (x * 100).toInt } val f4: Int => Double = { x => x + 1.5 } val f5: Double => Double = { x => x * 0.01 } val f6: Double => Double = { x => x - 200.0 } val f7: Double => Int = { x => x.toInt } val f8: Int => Int = { x => x + 10 } ! val baseline = { def F(x: Int) = f8(f7(f6(f5(f4(f3(f2(f1(x)))))))) x: Int => F(F(F(F(x)))) } ! val standardF = { def F = f1 andThen f2 andThen f3 andThen f4 andThen f5 andThen f6 andThen f7 andThen f8 F andThen F andThen F andThen F }
40. ### 4DBMBʹ͓͚Δؔ਺߹੒ class Comopse[A, B, C]( f: Function1[A, B], g: Function1[B,

C] ) extends Function1[A, B] { def apply(x: A) = g(f(a)) } Compose Function1 Compose Function1 Compose Function1 Compose Function1 Function1
41. ### ؔ਺߹੒͸ ಛघԽ͞Ε͍ͯͳ͍ • unspecialized(´ŋ_ŋ`) w ૊Έ߹ΘͤരൃΛݮΒͨ͢Ίͷ൑அͩͱࢥΘΕ·͢ @annotation.unspecialized def andThen[A](g: R

=> A): T1 => A = { x => g(apply(x)) }

͔͚ͨ݁ՌͩͱࢥΘΕΔ

45. ### ίϯύΠϧ࣌ͷ ࠷దԽ͸ ݶք͕͋Δ w ϥΠϒϥϦ͸ಈతʹϦϯΫ͞ΕΔͷͰɺΫϥεΛ௒ ͑ͨ࠷దԽ͸ඇৗʹ೉͍͠ w ಛघԽ͸ɺࣄલʹ͢΂ͯͷϓϦϛςΟϒܕͷ૊Έ߹ ΘͤΛ४උ͢Δ͜ͱ͸ࠔ೉ˠޮՌ͕ݶఆ͞ΕΔ w

NJOJCPYJOHΈ͍ͨͳςΫ͸͋Δ͚Ͳඪ४ϥΠ ϒϥϦʹಋೖ͞Εͯͳ͍ΜͰʜʜ

ཁ͕͋Δ

49. ### ࣮ߦϑΣʔζͷ෼ղ w ໨తͷΞϓϦέʔγϣϯ͸ɺΦϒδΣΫτάϥϑͷ ߏஙˠ࣮ߦͱ͍͏ߏ੒ def main() = { // ΦϒδΣΫτάϥϑͷߏங

val arrow: Long => Double = buildArrow() // ࣮ߦ while(true) { run(arrow) } }

51. ### ࠷దԽϑΣʔζͷಋೖ def main() = { // ΦϒδΣΫτάϥϑͷߏங val arrow: Long

=> Double = buildArrow() // ࠷దԽ val optimized = optimize(arrow) // ࣮ߦ while(true) { run(optimized) } }
52. ### खܰͳ࣮૷Ͱ ߴ଎Խͯ͠ΈΔ w ؔ਺߹੒ΛΫϥεʹ·ͱΊɺಛघԽϝιουΛ࢖ ͏ w Ծ૝ϝιουݺͼग़͠ͱCPYJOH͕໰୊ w \$PNQPTF/Έ͍ͨͳΫϥε࡞Ε͹ղܾ͢Δ w

ࣄલʹશύλʔϯੜ੒͸ݱ࣮తͰ͸ͳ͍ͷͰɺ࣮ߦ ࣌ʹ΍Δ
53. ### Ϋϥεੜ੒ʹΑΔ࣮૷ w +BWBTTJTUϥΠϒϥϦͰ͜͏͍͏ΫϥεΛಈతʹ ࡞Δ clas Compose5 extends Function1 { val

f1: Function1 val f2: Function1 // ... def apply(a: Any) = apply\$ID(a) def apply\$ID(a: Int): Double = { f5\$ID(f4\$II(f3\$DI(f2\$ID(f1\$II(a)))) } // ... }

͕ظ଴Ͱ͖Δ
55. ### MethodHandleʹΑΔ࣮૷ w MethodHandle+7.ʹ͓͚Δؔ਺ϙΠϯλ w +7.͕ಛผѻ͍ͯ͘͠ΕΔͷͰ࠷దԽͷΦϙνϡ χςΟ͕͓͓͖͍ w +7.࢓༷Ͱ΋ϝιουݺͼग़࣌͠ͷಛผѻ͍͕໌ ݴ͞ΕͯΔ w

.)ͷ߹੒΋αϙʔτ͍ͯ͠Δ
56. ### MethodHandle API w MethodHandles.identity(klass)߃౳ؔ਺ w MethodHandles.lookup().findVirtual(klass, name, type).bind(obj):ಛఆͷΠϯελϯεͷ Ծ૝ؔ਺Λද͢.)ΛಘΔ w

MethodHandles.filterReturnValue(mh1, mh2) .)ͷฦΓ஋ʹผͷ.)Λద༻ w ͜ΕΒΛ࢖͑͹ؔ਺߹੒͕දݱՄೳ
57. ### ϕϯνϚʔΫ݁Ռ w ͪΐͬͱ଎͘ͳΓ·ͨ͠Ͷ  w .FUIPE)BOEMF࢖͑͹Ϋϥεੜ੒ͳ͠ͰΦʔό ϔου࡟ݮͰ͖ΔͷͰ͓ಘ w ͔͠͠CBTFMJOF·Ͱ͸ԕ͍ standard

௨ৗͷؔ਺߹੒ 4515.900 ± 154.250 fast ߹੒Ϋϥεͷੜ੒ 5499.803 ± 183.904 fastMH MethodHandleʹΑΔ߹੒ 5476.340 ± 45.937 baseline ߹੒ͤͣ௚઀ݺͿ 21772.108 ± 154.944 ୯Ґ: k ops/sec

61. ### ϑΟʔϧυͷ༥߹ w Ծ૝ؔ਺ݺͼग़͠Λ࣮ؔ਺ݺͼग़͠ʹม׵Ͱ͖Δ w +*5ίϯύΠϧͰͷ࠷దԽ΋͖͖΍͘͢ͳΔ͔΋ class A(b: B) { def

foo = b.bar + 1 } class B(c: C) { def bar = 99 + c.baz } class C { def baz = 111 } class A_opt(b: B) extends A{ def foo = b_bar + 1 def b_bar = 99 + b_c_baz def b_c_baz = 111 }
62. ### ϝιουͷΠϯϥΠϯԽ w ϑΟʔϧυ༥߹ޙɺಉҰΠϯελϯε಺Ͱͷϝιο υΠϯϥΠϯԽΛߦ͏ class A_opt(b: B) extends A{ def

foo = b_bar + 1 def b_bar = 99 + b_c_baz def b_c_baz = 111 } class A_opt2(b: B) extends A{ def foo = 99 + 111 + 1 }
63. ### ϕϯν݁Ռ w ر๬͕ݟ͖͑ͯ·ͨ͠Ͷ w ؔ਺ݺͼग़͠ίετͷపఈͨ͠࡟ݮͱɺ+*5ίϯύΠϧʹΑΔ ࠷దԽ͕ޮ͖΍͍͢ܗࣜʹͳͬͨ͜ͱ͕଎౓ʹͭͳ͕ͬͨͱݟ ͍ͯ·͢ w CBTFMJOFͱͷࠩ͸ɺCPYJOH͕ফͤͯͳ͍ͷ͕ؔ܎ͯͦ͠͏ standard

௨ৗͷؔ਺߹੒ 4640.914 ± 77.983 fused Field fusionద༻ 7187.380 ± 321.257 fuseInlined Field Fusion + Method Inlining 12924.076 ± 207.785 baseline ߹੒ͤͣ௚઀ݺͿ 21841.596 ± 223.906 ୯Ґ: k ops/sec

71. ### Ϋϥεੜ੒ w ϑΟʔϧυʹద੾ͳ஋Ληοτ͢Δඞཁ͕͋Δ w ਌ΫϥεͷpOBMϑΟʔϧυʹ΋ w ਌ΫϥεͷίϯετϥΫλʹ͸ద੾ͳ஋Λ౉͞Ͷ͹ ͳΒͳ͍ w ਌ͷίϯετϥΫλΛղੳͯ͠Ҿ਺ͱϑΟʔϧυͷ

ؔ܎ΛϚοϐϯά͠ɺͦΕΛݩʹίϯετϥΫλ࣮ ૷ͱҾ਺ΛٻΊΔ
72. ### Ϋϥεੜ੒ ίϯετϥΫλղੳ w \$ͷαϒΫϥεΛఆ͍ٛͨ͠ w "Yͷ஋͸"ίϯετϥΫλͷୈҰҾ਺͕࢖ΘΕΔ w #Zͷ஋͸#ίϯετϥΫλͷୈҰҐҾ਺͕࢖ΘΕΔ w #ίϯετϥΫλ͸"

 ΛݺͿ w \$ίϯετϥΫλͷҾ਺͸Ͱ͋Δ΂͖ w ͱ͍͏͜ͱΛɺϑΟʔϧυͷ஋ͱ֤Ϋϥεఆ͔ٛΒٻΊΔ class A(val x: Int) class B(val y: Int) extends A(1) class C(val x: Int) extends B(x) ! optimize(new C(1))

77. ### ͲΜͳͱ͖ʹ༗ޮͳͷ ͔ w খ͞ͳΦϒδΣΫτ͕ଟ਺߹੒͞Ε͍ͯΔ w ΦϒδΣΫτͷੜ੒ճ਺࣮ߦճ਺ w ຊ౰ʹύϑΥʔϚϯε΍ϨΠςϯγ͕ॏཁ w ந৅ԽΛࣺͯͨ͘ͳ͍

w ৴߸ॲཧҎ֎ͩͱ w ݴޠॲཧܥ w Ҩ఻తϓϩάϥϛϯά w +BWBͷ1BUUFSOΫϥεʹ΋ద༻Ͱ͖Δ͔΋
78. ### ࠓޙͷల๬ w ·ͩαϙʔτͯ͠ͳ͍ཁૉ͕ଟ͍ w OFXͱ͔ྫ֎ϋϯυϥͱ͔ w ΠϯλϑΣʔεͷσϑΥϧτ࣮૷΍*O%Z w 4DBMBͰ࢖ͬͯͳ͍͍͍͔͠ͱࢥͬͨΒɺ࠾༻ ͷಈ͖͕

w ҆શͳॻ͖׵͑ͷอো w ͜ͷॻ͖׵͑͸Ͳ͏͍ͬͨ৚݅ͷ΋ͱͰ҆શͳͷ ͔ ͱ͍͏ͷΛ։ൃऀͷצʹཔ͍ͬͯΔ w ܗࣜతख๏ɺಋೖ͍ͨ͠Ͱ͢Ͷʜʜ
79. ### ؔ࿈ࢿྉ w 4PPU w όΠτίʔυղੳ࠷దԽϥΠϒϥϦͷ࿝ฮ w ͪ͜Β͸੩తͳม׵Λલఏͱ͍ͯ͠ΔΑ͏Ͱ͢ w 4USFBN+*5 w

\$PNNFOTBM\$PNQJMFS֓೦ w .FUIPE)BOEMFͷݩωλ w ੴ࡚Ұ໌ࢯͷ֤छࢿྉ w +7.͕࠾༻͍ͯ͠Δ࠷దԽख๏ʹ͍ͭͯͷوॏͳࢿྉ w ೥୅લ൒ʹॻ͔Εͨ΋ͷͰ͕͢ɺ+*5ίϯύΠϥͷॲཧʹͭ ͍ͯॻ͔Εͨࢿྉ͸ຊ౰ʹগͳ͍ͷͰوॏ w (JPSHJE[F (FPSHF.PEVMBS4ZOUIFTJ[FS1SPHSBNNJOHJO)BTLFMM%JTT.4D%JTTFSUBUJPO  %FQBSUNFOUPG\$PNQVUFS4DJFODFBOE&OHJOFFSJOH %JWJTJPOPG\$PNQVUJOH4DJFODF \$IBMNFST 6OJWFSTJUZPG5FDIOPMPHZBOE5IF6OJWFSTJUZPG(PUIFOCVSH (PUIFOCVSH 4XFEFO  w )BLFMM :BNQBͰϞδϡϥʔγϯη࡞Δ࿩