Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Devoxx UK 2015 Presentation: Miniboxing - Fast ...

Devoxx UK 2015 Presentation: Miniboxing - Fast Generics for Primitive Types

Miniboxing presentation at Devoxx UK 2015. Website: http://www.devoxx.co.uk/

The recording is available on parleys: https://www.parleys.com/tutorial/miniboxing-fast-generics-primitive-types

The two demos:
- Streams: not yet online
- Image processing: http://scala-miniboxing.org/example_pureimage.html

Project website: http://scala-miniboxing.org

Vlad Ureche

June 18, 2015
Tweet

More Decks by Vlad Ureche

Other Decks in Programming

Transcript

  1. scala-miniboxing.org @miniboxing Vlad URECHE PhD student in the Scala Team

    @ EPFL Working on program transformations in the Scala programming language, focusing on data representation. Contributions to specialization, backend and Scaladoc. @ @VladUreche @VladUreche [email protected]
  2. scala-miniboxing.org @miniboxing Compilers Compilers Source code (language 1) Source code

    (language 2) compiler C, C++, Java, Scala, C#, Haskell, Clojure, ... x86/ARM assembly LLVM bitcode Cuda code JVM bytecode .NET bytecode ...
  3. scala-miniboxing.org @miniboxing Compilers Compilers Source code (language 1) Source code

    (language 2) compiler C, C++, Java, Scala, C#, Haskell, Clojure, ... x86/ARM assembly LLVM bitcode Cuda code JVM bytecode .NET bytecode ... Why so much fuss ?
  4. scala-miniboxing.org @miniboxing Compilers Compilers Abstraction Imple- mentation compiler Variable Stack

    slot or Processor register or Heap location … Implementation details
  5. scala-miniboxing.org @miniboxing Erased Generics Erased Generics java.lang.Integer.valueOf(5) boxing is not

    great ... boxing is not great ... inflates heap requirements produces garbage
  6. scala-miniboxing.org @miniboxing Erased Generics Erased Generics java.lang.Integer.valueOf(5) boxing is not

    great ... boxing is not great ... inflates heap requirements produces garbage value is accessed indirectly (slow)
  7. scala-miniboxing.org @miniboxing Erased Generics Erased Generics java.lang.Integer.valueOf(5) boxing is not

    great ... boxing is not great ... inflates heap requirements produces garbage value is accessed indirectly (slow) breaks locality guarantees
  8. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

    def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t
  9. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

    def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t def identity_C(t: char): char = t
  10. scala-miniboxing.org @miniboxing Specialization Specialization def identity[T](t: T): T = t

    def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t def identity_C(t: char): char = t … (7 other variants)
  11. scala-miniboxing.org @miniboxing The idea behind The idea behind ... LONG

    DOUBLE INT FLOAT SHORT ... LONG DOUBLE INT FLOAT SHORT a long integer miniboxing miniboxing
  12. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

    def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t
  13. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

    def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t long encodes all primitive types
  14. scala-miniboxing.org @miniboxing Miniboxing Miniboxing def identity[T](t: T): T = t

    def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t Only 2n variants long encodes all primitive types
  15. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

    • Paper from 2014 • By Aggelos Biboudis, Uni of Athens
  16. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

    • Paper from 2014 • By Aggelos Biboudis, Uni of Athens • Comparing Steaming support in – in Java 8 – in Scala – in .NET
  17. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

    • Paper from 2014 • By Aggelos Biboudis, Uni of Athens • Comparing Steaming support in – in Java 8 – in Scala – in .NET • … but Scala did not have streaming support
  18. scala-miniboxing.org @miniboxing Clash of the Lambdas Clash of the Lambdas

    • Paper from 2014 • By Aggelos Biboudis, Uni of Athens • Comparing Steaming support in – in Java 8 – in Scala – in .NET • But Scala lacks an equivalent streaming support – Thus the numbers :)
  19. scala-miniboxing.org @miniboxing Warnings Warnings scala> def baz[T](t: T): T =

    t baz: [T](t: T)T scala> baz[Int](4) <console>:9: warning: The method baz would benefit from miniboxing type parameter T, since it is instantiated by a primitive type. ...
  20. scala-miniboxing.org @miniboxing Call Graph Call Graph def foo[T](t: T): T

    = bar(t) def bar[T](t: T): T = baz(t) def baz[T](t: T): T = t
  21. scala-miniboxing.org @miniboxing Call Graph Call Graph def foo[T](t: T): T

    = bar(t) def bar[T](t: T): T = baz(t) def baz[T](t: T): T = t call graph
  22. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph def foo[@miniboxed

    T](t: T): T = bar(t) def bar[@miniboxed T](t: T): T = baz(t) def baz[@miniboxed T](t: T): T = t
  23. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph def foo[@miniboxed

    T](t: T): T = bar(t) def bar[@miniboxed T](t: T): T = baz(t) def baz[@miniboxed T](t: T): T = t miniboxing
  24. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph def foo(...):

    ... = bar(t) def foo_M(...): ... = bar_M(t) def bar(...): ... = baz(t) def bar_M(...): ... = baz_M(t) def baz(...): ... = t def baz_M(...): ... = t
  25. scala-miniboxing.org @miniboxing Miniboxed Call Graph Miniboxed Call Graph foo foo_M

    bar bar_M baz baz_M Data is pased in the miniboxed encoding no boxing necessary!
  26. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph def foo[@miniboxed

    T](t: T): T = bar(t) def bar[@miniboxed T](t: T): T = baz(t) def baz[@miniboxed T](t: T): T = t
  27. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph def foo[@miniboxed

    T](t: T): T = bar(t) def bar[@miniboxed T](t: T): T = baz(t) def baz[@miniboxed T](t: T): T = t
  28. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph def foo[@miniboxed

    T](t: T): T = bar(t) def bar[@miniboxed T](t: T): T = baz(t) def baz[@miniboxed T](t: T): T = t miniboxing
  29. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph foo foo_M

    bar baz baz_M boxing arguments → warn there is a better version but I can't call it → warn
  30. scala-miniboxing.org @miniboxing Suboptimal Call Graph Suboptimal Call Graph scala> object

    Test { | def foo[@miniboxed T](t: T): T = bar(t) | def bar[ T](t: T): T = baz(t) | def baz[@miniboxed T](t: T): T = t | } <console>:10: warning: The method Test.bar would benefit from miniboxing type parameter T, since it is instantiated by miniboxed type parameter T of method foo: def foo[@miniboxed T](t: T): T = bar(t) ^ <console>:11: warning: The following code could benefit from miniboxing specialization if the type parameter T of method bar would be marked as "@miniboxed T": def bar[T](t: T): T = baz(t) ^ defined object Test
  31. scala-miniboxing.org @miniboxing Warnings Warnings • Miniboxing tries to avoid boxing

    • When it can't avoid it, it warns you – And you can act on it • Many other warnings – To keep you from shooting yourself in the foot
  32. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Replaces the library constructs –

    Functions – Arrays – Numeric type classes ... library ... library
  33. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Replaces the library constructs –

    Functions – Arrays – Numeric type classes • Adds – Interfaces to other constructs – Miniboxed state reflection ... library ... library
  34. scala-miniboxing.org @miniboxing Miniboxing Miniboxing • Replaces the library constructs –

    Functions – Arrays – Numeric type classes • Adds – Interfaces to other constructs – Miniboxed state reflection ... library ... library Am I inside a miniboxed class? If so, what is T?
  35. scala-miniboxing.org @miniboxing Credits and Thank you-s • Martin Odersky -

    without Scala, there would be no miniboxing • Cristian Talau - developed the initial prototype, as a semester project • Milos Stojanovic - work on warnings, tuple accessors and others • Romain Beguet - work on miniboxed arrays • Eugene Burmako - the value class plugin based on the LDL transformation • Aymeric Genet - developing collection-like benchmarks for the miniboxing plugin • Martin Odersky, for his patient guidance • Dmitry Petrashko, for the many cool discussions we had • Ilya Klyuchnikov and Pablo Guerrero - fixes and commits • Iulian Dragos, for his work on specialization and many explanations • Miguel Garcia, for his original insights that spawned the miniboxing idea • Michel Schinz, for his wonderful comments and enlightening ACC course • Andrew Myers and Roland Ducournau for the discussions we had and the feedback provided • Heather Miller for the eye-opening discussions we had • Vojin Jovanovic, Sandro Stucki, Manohar Jonalagedda and the whole LAMP laboratory in EPFL • Adriaan Moors, for the miniboxing name which stuck :)) • Thierry Coppey, Vera Salvisberg and George Nithin, for the feedback
  36. scala-miniboxing.org @miniboxing Credits and Thank you-s • Grzegorz Kossakowski, for

    the many brainstorming sessions on specialization • Erik Osheim, Tom Switzer and Rex Kerr for their guidance on the Scala community side • Sandro, Vojin, Nada, Heather, Manohar - reviews and discussions on the LDL paper • Hubert Plociniczak for the type notation in the LDL paper • Denys Shabalin (@densh), Dmitry Petrashko (@darkdimius) for their patient reviews of the LDL paper • Alexandru Nedelcu (@alex_ndc) - for the functions direction • Stu Hood (@stuhood) - for the initial support, ideas • Julien Truffault (@JulienTruffaut) - for motivating the development of tuple accessors, sticky plugin warnings • Aggelos Biboudis (@biboudis) - for pushing the functions project forward and the stream benchmarks • Tom Switzer (@tixxit) - for pushing the array project forward and the vector benchmarks • Philip Stutz (@PhilipStutz) - for the ideas on warnings • Rex Kerr (@ichoran) - for ideas on reflection • Vlad Patryshev (@vpatryshev) - for organizing the Scala Bay Meetup, wehre I presented once • The Scala Community • The Valhalla Project Architects • The Devoxx, PNWScala and ScalaDays organizers!
  37. scala-miniboxing.org @miniboxing PureImage PureImage • has very nice abstractions –

    generalizes over input, output format – generalizes over pixel format – provides collection-like mapping over images • liked it a lot
  38. scala-miniboxing.org @miniboxing PureImage PureImage • took the usual path to

    using miniboxing – code up a mock-up – become familiar with the problem – try out miniboxing on a small scale
  39. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Image[Repr: Pixel]

    { def width: Int def height: Int def apply(x: Int, y: Int): Repr def map[Repr2: Pixel](f: Image[Repr] => Generator[Repr2]): Image[Repr2] }
  40. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Image[Repr: Pixel]

    { def width: Int def height: Int def apply(x: Int, y: Int): Repr def map[Repr2: Pixel](f: Image[Repr] => Generator[Repr2]): Image[Repr2] } What's a generator?
  41. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Generator[Repr: Pixel]

    { def width: Int def height: Int def generate(x: Int, y: Int): Repr }
  42. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Generator[Repr: Pixel]

    { def width: Int def height: Int def generate(x: Int, y: Int): Repr } Why generic? What is pixel?
  43. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels
  44. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Transformed image 8-bit RGBA channels ...
  45. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ...
  46. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ... discretization after each filter => artifacts
  47. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ... discretization after each filter => artifacts double precision RGBA double precision RGBA
  48. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ... discretization after each filter => artifacts double precision RGBA double precision RGBA discretization only when saving the file => better quality
  49. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up Image on disk Indexed

    colors Loaded image 8-bit RGBA channels Transformed image 8-bit RGBA channels Image on disk Indexed colors Transformed image 8-bit RGBA channels ... discretization after each filter => artifacts double precision RGBA double precision RGBA discretization only when saving the file => better quality Pixel representation
  50. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Pixel[Repr: Manifest]

    { def r(t: Repr): Double // red def g(t: Repr): Double // green def b(t: Repr): Double // blue def a(t: Repr): Double // alpha def pack(r: Double, g: Double, b: Double, a: Double): Repr ... }
  51. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Pixel[Repr: Manifest]

    { def r(t: Repr): Double // red def g(t: Repr): Double // green def b(t: Repr): Double // blue def a(t: Repr): Double // alpha def pack(r: Double, g: Double, b: Double, a: Double): Repr ... } All transformations occur on doubles
  52. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up abstract class Pixel[Repr: Manifest]

    { def r(t: Repr): Double // red def g(t: Repr): Double // green def b(t: Repr): Double // blue def a(t: Repr): Double // alpha def pack(r: Double, g: Double, b: Double, a: Double): Repr ... } All transformations occur on doubles But the data can be encoded differently
  53. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up object RGBA extends Pixel[Int]

    { ... } object RGBAExtended extends Pixel[Long] { ... } Encoding all channels
  54. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up object RGBA extends Pixel[Int]

    { ... } object RGBAExtended extends Pixel[Long] { ... } case class DiscreteChannels[T](r: T, g: T, b: T, a: T) object FullPixel extends FourChannelPixel[Double] object HalfPixel extends FourChannelPixel[Float] Encoding all channels
  55. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up object RGBA extends Pixel[Int]

    { ... } object RGBAExtended extends Pixel[Long] { ... } case class DiscreteChannels[T](r: T, g: T, b: T, a: T) object FullPixel extends FourChannelPixel[Double] object HalfPixel extends FourChannelPixel[Float] Storing channels individually Encoding all channels
  56. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up "More London Office Development

    at Dusk, London, UK - Diliff" by Diliff - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons - https://commons.wikimedia.org/wiki/File:More_London_Office_Development_at_Dusk,_London,_UK_-_Diliff.jpg
  57. scala-miniboxing.org @miniboxing PureImage Mock-up PureImage Mock-up "More London Office Development

    at Dusk, London, UK - Diliff" by Diliff - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons - https://commons.wikimedia.org/wiki/File:More_London_Office_Development_at_Dusk,_London,_UK_-_Diliff.jpg