EPFL Working on program transformations in the Scala programming language, focusing on data representation. @ @VladUreche @VladUreche [email protected]
and Employee can't be optimized • Together, Vector[Employee] can be optimized NAME ... NAME VectorOfEmployee ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY 5x faster
and Employee can't be optimized • Together, Vector[Employee] can be optimized NAME ... NAME VectorOfEmployee ID ID ... ... SALARY SALARY Vector[Employee] ID NAME SALARY ID NAME SALARY 5x faster Current challenge: No means of communicating this to the compiler
in the host language – entry point: data (targeted via types) – changes: data representation and operations object VectorOfEmployeeSoA extends Transformation { type Target = Vector[Employee] type Result = VectorOfEmployee // conversions, operations, ... }
• based on experience • based on speculation • one-time effort • repetitive and simple • affects code readability • is verbose • is error-prone compiler (automated)
– Storing transformation metadata • Overriding and the object model – Different signatures may not override • Passing values between scopes (composition) – Redundant conversions – Safety
– Storing transformation metadata • Overriding and the object model – Different signatures may not override • Passing values between scopes (composition) – Redundant conversions – Safety • Addressed in the compiler :)
meta-programming – Splitting the responsibility: • Defining the Transformation programmer → • Applying the Transformation compiler → – Scopes • Adapt the data representation to the operation • Allow speculating properties of the scope
without regret” - Tiark Rompf – DSLs small enough to be staged → • 10000x speed improvements – Scala too large to obtain any benefit → • Separate compilation/modularization • Dynamic dispatch • Aliasing • Reflection
without regret” - Tiark Rompf – DSLs small enough to be staged → • 10000x speed improvements – Scala too large to obtain any benefit → • Separate compilation/modularization • Dynamic dispatch • Aliasing • Reflection not supported by staging. If we add support, we lose the ability to optimize
machine support – Access to the low-level code – Can assume a (local) closed world – Can speculate based on profiles – On the critical path • Limited profiles • Limited inlining • Limited analysis – Biggest opportunities are high-level - O(n2) O(n) → • Incoming code is low-level • Rarely possible to recover them
machine support – Access to the low-level code – Can assume a (local) closed world – Can speculate based on profiles – On the critical path • Limited profiles • Limited inlining • Limited analysis – Biggest opportunities are high-level - O(n2) O(n) → • Incoming code is low-level • Rarely possible to recover them Typical solution: Metaprogramming
Full-fledged program transformers – :) Lots of power – :( Lots of responsibility • Compiler invariants • Object-oriented model • Modularity def optimize(tree: Tree): Tree = { ... }
Full-fledged program transformers – :) Lots of power – :( Lots of responsibility • Compiler invariants • Object-oriented model • Modularity def optimize(tree: Tree): Tree = { ... } Can we make metaprogramming “high-level”?