Generating Multithreaded Code from Parallel Haskell for Symmetric Multiprocessors Alejandro Caro

Total Page:16

File Type:pdf, Size:1020Kb

Generating Multithreaded Code from Parallel Haskell for Symmetric Multiprocessors Alejandro Caro Generating Multithreaded Code from Parallel Haskell for Symmetric Multiprocessors by Alejandro Caro S.B., Computer Science and Engineering, MIT 1990 S.M., Electrical Engineering and Computer Science, MIT 1993 Engineer in Computer Science, MIT 1998 Submitted to the Department of Electrical Engineering and Computer Science in partial fulfillment of the requirements for the degree of Doctor of Philosophy at the MASSACHUSETTS INSTITUTE OF TECHNOLOGY February 1999 @ 1999 Massachusetts Institute of Technology. All rights reserved. A u th or ....................... ....... ......... ................ Department 4f Electrical Engineering and Computer Science January 27, 1999 Certified by .:... .....- :...... 5.< ....... ............. V.. Arvind.I..v( Johnson Professor of Computer Science Thesis Supervisor 2' Accepted by .. .... .... .. .. .... Arthur C. Smith Chairman, Departmeital Committee on Graduate Students Generating Multithreaded Code from Parallel Haskell for Symmetric Multiprocessors by Alejandro Caro Submitted to the Department of Electrical Engineering and Computer Science on January 27, 1999, in partial fulfillment of the requirements for the degree of Doctor of Philosophy Abstract This dissertation presents pHc, a new compiler for Parallel Haskell (pH) with complete support for the entire language. pH blends the powerful features of a high-level, higher- order language with implicitly parallel, non-strict semantics. The result is a language that is easy to use but tough to compile. The principal contribution of this work is a new code- generation algorithm that works directly on A*, a terse intermediate representation based on the A-calculus. All the power of the original language is preserved in A*, and in addition, the new representation makes it easy to express the important concept of threads, groups of expressions that can execute sequentially, at a high-level. Code generation proceeds in two steps. First, the compiler turns A* programs into mul- tithreaded code for the Shared-Memory Threaded (SMT) machine, an abstract symmetric multiprocessor (SMP). The SMT machine simplifies the code-generator, by providing special mechanisms for parallelism, and improves its portability, by isolating it from any partic- ular SMP. Unlike previous compilers for similar languages, the SMT code generated by pHc makes use of suspensive threads for better use of sequential processors. Second, the compiler transforms SMT instructions into executable code. In keeping with the goals of simplicity and portability, the final product is emitted as a C program, with some exten- sions for compiler-controlled multithreading. This code is linked with a Run-Time System (RTS) that provides two facilities: a work-stealing scheduler and a memory manager with garbage-collection. To evaluate the performance of the code, we generated instrumented programs. Us- ing a small but varied set of benchmarks, we measured the components of run-time, the instruction mix, the scalability of code up to eight processors, and as a comparison, the single-processor performance against two of the latest Haskell compilers. We found encour- aging speedups up to four processors, but rarely beyond. Moreover, we found substantial overhead in single-processor performance. These results are consistent with our emphasis on completeness and correctness first and on performance second. We conclude with some suggestions for future work that will remedy some of the shortcomings discovered in the evaluation. Thesis Supervisor: Arvind Title: Johnson Professor of Computer Science Acknowledgments I have been part of the Computation Structures Group for ten years, and in that decade, I have gone from queasy undergraduate to confident, some would say hardened, graduate. I cannot imagine time better spent. Through it all, Arvind has been the steady helm of CSG, and from his insights and his approach to hard questions, I have learned the course to good research. It follows a deceptively simple bearing: choose your work because you find it worthwhile, not because it is the fashion, and do it until you think it complete, not until others happen to judge it so. None of us can predict the long-term impact of our research, but work of high quality will not easily founder. CSG originally attracted me because its dataflow projects involved a rethinking of com- puting from top to bottom. In Monsoon and StarT, we did it all, from programming language theory to high-performance hardware design. But none of this would have been possible without a superb crew. Together we tackled problems that were big, tough, un- yielding, and we persevered in the face of more obstacles than we care to remember. I was especially lucky to have worked closely with several generations, in particular Shail Aditya, Boon Ang, Andy Boughton, Derek Chiou, James Hoe, Jamie Hicks, Chris Joerg, R. Paul Johnson, Jan-Willem Maessen, and Ken Traub. I was fortunate too in my choice of thesis committee. In Martin Rinard and Vivek Sarkar, I found not only two experts in parallel compilers, which is rare enough, but also two enthusiastic and approachable colleagues, which was a real treat. This dissertation was markedly improved by their keen observations. Finally, as this long journey comes to an end, my thoughts turn to my family. Their unwavering faith in its successful completion stayed mine during some crushing ebbs. It is because of them that I never felt alone, and it is to them that I dedicate this work. A mi familia, con mucho carifio. Contents 1 Introduction 15 1.1 pH: Parallel Programming Made Easy 15 1.2 Complications . .. ... .. .. ... 16 1.3 Contributions .. .... ... .... 17 1.4 Dissertation Overview . ... ... .. 18 2 Parallel Haskell 19 2.1 Origins and Design .. 19 2.2 Type System . .. .. 22 2.3 Higher-Order Functions 24 2.4 Implicit Parallelism. 26 2.5 Lenient Evaluation . .. 27 2.6 Synchronizing Memory . 30 2.7 Barriers . .. .. .. .. 33 2.8 The A*-Calculus . 35 2.9 Summary .. .. .. 38 3 Compilation Challenges 41 3.1 Polymorphism. .. .. ... ... ... .. 41 3.2 Higher Order Functions . .. .. .. ... .. 44 3.3 Non-Strictness . .. .. 49 3.4 Synchronizing Memory . 55 3.5 Barriers . .. .. 57 3.6 Garbage Collection . .. 58 3.7 Summary . .. .. 59 9 4 The SMT Machine 61 4.1 Overview .... .. .. .. .. .. .. .. .. .. 6 2 4.2 Arithmetic and Move: plus, etc., and move ......... .. .. 66 4.3 Control Flow: jump and switch .. ... .. ... .. .. .. .. .. 66 4.4 Scheduling: spawn and schedule .. ... ... ... .. .. ... .. ... 67 4.5 Memory: allocate, load, touch, store, istore, and take .. .. ... .. ... 69 4.6 Barrier Instructions: initbar, touchbar, incbar, and decbar .. .. ... .. .. 72 4.7 Sum m ary ... .... ... ... ... .... ... ... .. .. .. .. 74 5 Compiling A* to SMT 75 5.1 Execution Environment . ... ... ... .... ... 75 5.2 Compiling Simple, Primitive, and Data Expressions ... .. ... .. .. 80 5.3 Compiling Case Expressions .. ... ... .... ... ... .... .. 86 5.4 Compiling A-Abstractions and Function Calls 87 5.5 Compiling Letrec Expressions .. ....... 100 5.6 Compiling Programs ........ ...... 109 5.7 Sum m ary ........ ......... .. .. .. 112 6 Better Threaded Code 113 6.1 Suspensive versus Non-Suspensive Threads . ..... .... .... 114 6.2 SMT Code from Threaded Programs . ... .. .. .. .. .. .. 116 6.3 Optimizations Enabled by Threading . .. .. .. .. .. .. .. 123 6.4 Partitioning ... ... .... .... .... .. .. .. .. .. .. 130 6.5 Partitioning in pHc .. ... .... .... .. ... .. .. ... 133 6.6 Partitioning fib . ... ... .... ... .. .. .. .. .. .. 135 6.7 Threading fib .. ... ... ... ... .. ... .. .. .. ... .. 136 6.8 When Programs Become Too Serial .. ... ... ... ... ... .. 141 6.9 Incremental Spawning . ..... ..... .. ... ... ... ... 143 6.10 Summary .... ... .... .... .... ... ... .... ... 143 7 Executable Code Generation 145 7.1 Implementing SMT Processors ... ... 146 7.2 Implementing the Global Work-Queue . 151 10 7.3 pH Data Representation .. .. ... .. ... .. ... ... ... .. ... 155 7.4 Choices for Code Generation . ... ... .. ... .. ... ... .. ... 160 7.5 Avoiding Stack Allocation .. ... ... ... ... .. .. .. .. .. .. 162 7.6 Implementing SMT Instructions . ... ... ... .. .. .. ... ... .. 165 7.7 Garbage Collection .. ... ... ... ... ... ... .. ... ... .. .. 178 7.8 Machine Dependences and Porting .. ... ... .. .... .... ... 180 7.9 Summary . ... ... ... ... .. ... ... ... ...... ...... 181 8 Preliminary Evaluation 183 8.1 Experimental Setup . ... .. ... .. .. .... ... 183 8.2 Components of Execution Time . .... .. .. ... ... 185 8.3 Instruction Mix . .. ... .. .. .. ... ... ... .. 187 8.4 Touch Behavior .. ... ... ... ... .. .. ... ... 189 8.5 Speedup .. .. .. .. .. .. .. ... .. .. ... ... .. ... ... .. 190 8.6 Single-Processor Performance vs. Haskell . ... .. .. .. ... .. .. 191 . 8.7 Summary ... ... ... .. ... ... .. .. ... ... .. ... ... .. 195 9 Related Work 197 9.1 Id/pH Compilers .. ... .. ... .. ... .. ... .. ... .. .. .. 197 9.2 Concurrent and Parallel Versions of Haskell . ... .. ... ... .. ... 200 9.3 Cilk Scheduling ... .. ... ... ... .. ... ... ... .. ... ... 202 10 Conclusion 203 10.1 Contributions . ... ... .. ... ... ... ... ... ... .. ... .. 203 10.2 Future Work ... ... .. ... ... .. ... ... .. ... ... .. .. 204 10.3 Conclusion .. .. ... .. ... .. ... .. ... .. ... .. .. ... 207 A Semantics of As 213 A.1 Syntax for As -... - . - .. ... .. .. .. ... .. .. ... .. .. 214 A.2 Contexts in As . - . .. - . --- -- --- -- --- .- .. ... .. 215 A.3 Equivalence Rules for As . - --- --- ---- - . ... 216 A.4 Reduction Rules for As
Recommended publications
  • Reversible Programming with Negative and Fractional Types
    9 A Computational Interpretation of Compact Closed Categories: Reversible Programming with Negative and Fractional Types CHAO-HONG CHEN, Indiana University, USA AMR SABRY, Indiana University, USA Compact closed categories include objects representing higher-order functions and are well-established as models of linear logic, concurrency, and quantum computing. We show that it is possible to construct such compact closed categories for conventional sum and product types by defining a dual to sum types, a negative type, and a dual to product types, a fractional type. Inspired by the categorical semantics, we define a sound operational semantics for negative and fractional types in which a negative type represents a computational effect that “reverses execution flow” and a fractional type represents a computational effect that“garbage collects” particular values or throws exceptions. Specifically, we extend a first-order reversible language of type isomorphisms with negative and fractional types, specify an operational semantics for each extension, and prove that each extension forms a compact closed category. We furthermore show that both operational semantics can be merged using the standard combination of backtracking and exceptions resulting in a smooth interoperability of negative and fractional types. We illustrate the expressiveness of this combination by writing a reversible SAT solver that uses back- tracking search along freshly allocated and de-allocated locations. The operational semantics, most of its meta-theoretic properties, and all examples are formalized in a supplementary Agda package. CCS Concepts: • Theory of computation → Type theory; Abstract machines; Operational semantics. Additional Key Words and Phrases: Abstract Machines, Duality of Computation, Higher-Order Reversible Programming, Termination Proofs, Type Isomorphisms ACM Reference Format: Chao-Hong Chen and Amr Sabry.
    [Show full text]
  • Let's Get Functional
    5 LET’S GET FUNCTIONAL I’ve mentioned several times that F# is a functional language, but as you’ve learned from previous chapters you can build rich applications in F# without using any functional techniques. Does that mean that F# isn’t really a functional language? No. F# is a general-purpose, multi paradigm language that allows you to program in the style most suited to your task. It is considered a functional-first lan- guage, meaning that its constructs encourage a functional style. In other words, when developing in F# you should favor functional approaches whenever possible and switch to other styles as appropriate. In this chapter, we’ll see what functional programming really is and how functions in F# differ from those in other languages. Once we’ve estab- lished that foundation, we’ll explore several data types commonly used with functional programming and take a brief side trip into lazy evaluation. The Book of F# © 2014 by Dave Fancher What Is Functional Programming? Functional programming takes a fundamentally different approach toward developing software than object-oriented programming. While object-oriented programming is primarily concerned with managing an ever-changing system state, functional programming emphasizes immutability and the application of deterministic functions. This difference drastically changes the way you build software, because in object-oriented programming you’re mostly concerned with defining classes (or structs), whereas in functional programming your focus is on defining functions with particular emphasis on their input and output. F# is an impure functional language where data is immutable by default, though you can still define mutable data or cause other side effects in your functions.
    [Show full text]
  • Notes on Functional Programming with Haskell
    Notes on Functional Programming with Haskell H. Conrad Cunningham [email protected] Multiparadigm Software Architecture Group Department of Computer and Information Science University of Mississippi 201 Weir Hall University, Mississippi 38677 USA Fall Semester 2014 Copyright c 1994, 1995, 1997, 2003, 2007, 2010, 2014 by H. Conrad Cunningham Permission to copy and use this document for educational or research purposes of a non-commercial nature is hereby granted provided that this copyright notice is retained on all copies. All other rights are reserved by the author. H. Conrad Cunningham, D.Sc. Professor and Chair Department of Computer and Information Science University of Mississippi 201 Weir Hall University, Mississippi 38677 USA [email protected] PREFACE TO 1995 EDITION I wrote this set of lecture notes for use in the course Functional Programming (CSCI 555) that I teach in the Department of Computer and Information Science at the Uni- versity of Mississippi. The course is open to advanced undergraduates and beginning graduate students. The first version of these notes were written as a part of my preparation for the fall semester 1993 offering of the course. This version reflects some restructuring and revision done for the fall 1994 offering of the course|or after completion of the class. For these classes, I used the following resources: Textbook { Richard Bird and Philip Wadler. Introduction to Functional Program- ming, Prentice Hall International, 1988 [2]. These notes more or less cover the material from chapters 1 through 6 plus selected material from chapters 7 through 9. Software { Gofer interpreter version 2.30 (2.28 in 1993) written by Mark P.
    [Show full text]
  • Engineering Definitional Interpreters
    Reprinted from the 15th International Symposium on Principles and Practice of Declarative Programming (PPDP 2013) Engineering Definitional Interpreters Jan Midtgaard Norman Ramsey Bradford Larsen Department of Computer Science Department of Computer Science Veracode Aarhus University Tufts University [email protected] [email protected] [email protected] Abstract In detail, we make the following contributions: A definitional interpreter should be clear and easy to write, but it • We investigate three styles of semantics, each of which leads to may run 4–10 times slower than a well-crafted bytecode interpreter. a family of definitional interpreters. A “family” is characterized In a case study focused on implementation choices, we explore by its representation of control contexts. Our best-performing ways of making definitional interpreters faster without expending interpreter, which arises from a natural semantics, represents much programming effort. We implement, in OCaml, interpreters control contexts using control contexts of the metalanguage. based on three semantics for a simple subset of Lua. We com- • We evaluate other implementation choices: how names are rep- pile the OCaml to 86 native code, and we systematically inves- x resented, how environments are represented, whether the inter- tigate hundreds of combinations of algorithms and data structures. preter has a separate “compilation” step, where intermediate re- In this experimental context, our fastest interpreters are based on sults are stored, and how loops are implemented. natural semantics; good algorithms and data structures make them 2–3 times faster than na¨ıve interpreters. Our best interpreter, cre- • We identify combinations of implementation choices that work ated using only modest effort, runs only 1.5 times slower than a well together.
    [Show full text]
  • An Architectural Trail to Threaded-Code Systems
    Some programmers question certain claims made for threaded-code systems. The author defends these claims by tracing such a system from its origin in simple concepts. An Architectural Trail to Threaded-Code Systems Peter M. Kogge, IBM Federal Systems Division Interest in software systems based on threaded-code * the concepts and syntax of a high-order language, or concepts has grown remarkably in recent years. Ad- HOL; and vocates of such systems regularly make claims for them * a set of commands for a conversational monitor. that many classical programmers regard as bordering on The ISA (such as it is) is for an abstract machine that is the impossible. Typically, proponents claim that it is very efficiently implemented by short code segments in possible to construct, in 5K to 10K bytes of code, a soft- almost any current machine architecture. The HOL con- ware package that cepts include hierarchical construction of programs, * is conversational like APL, Lisp, or Basic; block structures, GOTOless programming, and user- * includes a compile facility with many high-order definable data structures. The commands for the conver- language, structured-programming constructs; sational monitor permit direct interaction with objects * exhibits performance very close to that of machine- defined by the programmer in terms he defines, not sim- coded program equivalents; ply in the terms of the underlying machine (i.e., core * is written largely in itself and consequently is largely dumps). Further, the command set is directly executable portable; in a conversational mode and includes virtually all com- * places no barriers among combinations of system, mands available in the system; when so executed, they compiler, or application code; function just as they would if found in an executed pro- * can include an integrated, user-controlled virtual gram.
    [Show full text]
  • Design Patterns in Ocaml
    Design Patterns in OCaml Antonio Vicente [email protected] Earl Wagner [email protected] Abstract The GOF Design Patterns book is an important piece of any professional programmer's library. These patterns are generally considered to be an indication of good design and development practices. By giving an implementation of these patterns in OCaml we expected to better understand the importance of OCaml's advanced language features and provide other developers with an implementation of these familiar concepts in order to reduce the effort required to learn this language. As in the case of Smalltalk and Scheme+GLOS, OCaml's higher order features allows for simple elegant implementation of some of the patterns while others were much harder due to the OCaml's restrictive type system. 1 Contents 1 Background and Motivation 3 2 Results and Evaluation 3 3 Lessons Learned and Conclusions 4 4 Creational Patterns 5 4.1 Abstract Factory . 5 4.2 Builder . 6 4.3 Factory Method . 6 4.4 Prototype . 7 4.5 Singleton . 8 5 Structural Patterns 8 5.1 Adapter . 8 5.2 Bridge . 8 5.3 Composite . 8 5.4 Decorator . 9 5.5 Facade . 10 5.6 Flyweight . 10 5.7 Proxy . 10 6 Behavior Patterns 11 6.1 Chain of Responsibility . 11 6.2 Command . 12 6.3 Interpreter . 13 6.4 Iterator . 13 6.5 Mediator . 13 6.6 Memento . 13 6.7 Observer . 13 6.8 State . 14 6.9 Strategy . 15 6.10 Template Method . 15 6.11 Visitor . 15 7 References 18 2 1 Background and Motivation Throughout this course we have seen many examples of methodologies and tools that can be used to reduce the burden of working in a software project.
    [Show full text]
  • Scala by Example (2009)
    Scala By Example DRAFT January 13, 2009 Martin Odersky PROGRAMMING METHODS LABORATORY EPFL SWITZERLAND Contents 1 Introduction1 2 A First Example3 3 Programming with Actors and Messages7 4 Expressions and Simple Functions 11 4.1 Expressions And Simple Functions...................... 11 4.2 Parameters.................................... 12 4.3 Conditional Expressions............................ 15 4.4 Example: Square Roots by Newton’s Method................ 15 4.5 Nested Functions................................ 16 4.6 Tail Recursion.................................. 18 5 First-Class Functions 21 5.1 Anonymous Functions............................. 22 5.2 Currying..................................... 23 5.3 Example: Finding Fixed Points of Functions................ 25 5.4 Summary..................................... 28 5.5 Language Elements Seen So Far....................... 28 6 Classes and Objects 31 7 Case Classes and Pattern Matching 43 7.1 Case Classes and Case Objects........................ 46 7.2 Pattern Matching................................ 47 8 Generic Types and Methods 51 8.1 Type Parameter Bounds............................ 53 8.2 Variance Annotations.............................. 56 iv CONTENTS 8.3 Lower Bounds.................................. 58 8.4 Least Types.................................... 58 8.5 Tuples....................................... 60 8.6 Functions.................................... 61 9 Lists 63 9.1 Using Lists.................................... 63 9.2 Definition of class List I: First Order Methods..............
    [Show full text]
  • Open Programming Language Interpreters
    Open Programming Language Interpreters Walter Cazzolaa and Albert Shaqiria a Università degli Studi di Milano, Italy Abstract Context: This paper presents the concept of open programming language interpreters, a model to support them and a prototype implementation in the Neverlang framework for modular development of programming languages. Inquiry: We address the problem of dynamic interpreter adaptation to tailor the interpreter’s behaviour on the task to be solved and to introduce new features to fulfil unforeseen requirements. Many languages provide a meta-object protocol (MOP) that to some degree supports reflection. However, MOPs are typically language-specific, their reflective functionality is often restricted, and the adaptation and application logic are often mixed which hardens the understanding and maintenance of the source code. Our system overcomes these limitations. Approach: We designed a model and implemented a prototype system to support open programming language interpreters. The implementation is integrated in the Neverlang framework which now exposes the structure, behaviour and the runtime state of any Neverlang-based interpreter with the ability to modify it. Knowledge: Our system provides a complete control over interpreter’s structure, behaviour and its runtime state. The approach is applicable to every Neverlang-based interpreter. Adaptation code can potentially be reused across different language implementations. Grounding: Having a prototype implementation we focused on feasibility evaluation. The paper shows that our approach well addresses problems commonly found in the research literature. We have a demon- strative video and examples that illustrate our approach on dynamic software adaptation, aspect-oriented programming, debugging and context-aware interpreters. Importance: Our paper presents the first reflective approach targeting a general framework for language development.
    [Show full text]
  • 61A Lecture 6 Lambda Expressions VS Currying
    Announcements • Homework 2 due Tuesday 9/17 @ 11:59pm • Project 2 due Thursday 9/19 @ 11:59pm • Optional Guerrilla section next Monday for students to master higher-order functions . Organized by Andrew Huang and the readers 61A Lecture 6 . Work in a group on a problem until everyone in the group understands the solution • Midterm 1 on Monday 9/23 from 7pm to 9pm Friday, September 13 . Details and review materials will be posted early next week . There will be a web form for students who cannot attend due to a conflict 2 Lambda Expressions >>> ten = 10 An expression: this one evaluates to a number >>> square = x * x Also an expression: evaluates to a function Lambda Expressions >>> square = lambda x: x * x Important: No "return" keyword! A function with formal parameter x that returns the value of "x * x" >>> square(4) 16 Must be a single expression Lambda expressions are not common in Python, but important in general (Demo) Lambda expressions in Python cannot contain statements at all! 4 Lambda Expressions Versus Def Statements def square(x): square = lambda x: x * x VS return x * x • Both create a function with the same domain, range, and behavior. • Both functions have as their parent the environment in which they were defined. Currying • Both bind that function to the name square. • Only the def statement gives the function an intrinsic name. The Greek letter lambda Example: http://goo.gl/XH54uE 5 Function Currying def make_adder(n): return lambda k: n + k >>> make_adder(2)(3) There's a general 5 relationship between (Demo) >>> add(2, 3) these functions 5 Newton's Method Currying: Transforming a multi-argument function into a single-argument, higher-order function.
    [Show full text]
  • A Hybrid Approach of Compiler and Interpreter Achal Aggarwal, Dr
    International Journal of Scientific & Engineering Research, Volume 5, Issue 6, June-2014 1022 ISSN 2229-5518 A Hybrid Approach of Compiler and Interpreter Achal Aggarwal, Dr. Sunil K. Singh, Shubham Jain Abstract— This paper essays the basic understanding of compiler and interpreter and identifies the need of compiler for interpreted languages. It also examines some of the recent developments in the proposed research. Almost all practical programs today are written in higher-level languages or assembly language, and translated to executable machine code by a compiler and/or assembler and linker. Most of the interpreted languages are in demand due to their simplicity but due to lack of optimization, they require comparatively large amount of time and space for execution. Also there is no method for code minimization; the code size is larger than what actually is needed due to redundancy in code especially in the name of identifiers. Index Terms— compiler, interpreter, optimization, hybrid, bandwidth-utilization, low source-code size. —————————— —————————— 1 INTRODUCTION order to reduce the complexity of designing and building • Compared to machine language, the notation used by Icomputers, nearly all of these are made to execute relatively programming languages closer to the way humans simple commands (but do so very quickly). A program for a think about problems. computer must be built by combining some very simple com- • The compiler can spot some obvious programming mands into a program in what is called machine language. mistakes. Since this is a tedious and error prone process most program- • Programs written in a high-level language tend to be ming is, instead, done using a high-level programming lan- shorter than equivalent programs written in machine guage.
    [Show full text]
  • Basic Threads Programming: Standards and Strategy
    Basic Threads Programming: Standards and Strategy Mike Dahlin [email protected] February 13, 2007 1 Motivation Some people rebel against coding standards. I don’t understand the logic. For concurrent programming in particular, there are a few good solutions that have stood the test of time (and many unhappy people who have departed from these solutions.) For concurrent programming, debugging won’t work. You must rely on (a) writing correct code and (b) writing code that you and others can read and understand. Following the rules below will help you write correct, readable code. Rules 2 through 6 below are required coding standards for CS372. Answers to homework and exam problems and project code that do not follow these standards are by definition incorrect. Section 5 discusses additional restrictions for project code (or exam pseudo-code) in Java. Again, answers that deviate from these required coding standars are, by definition, incorrect for this class. If you believe you have a better way to write concurrent programs, that’s great! Bring it to us (before you use it on an assignment!) We will examine your approach the same way we hope that a civil engineering manager would examine a proposal by a bright young civil engineer who has a proposal for a better config- uration of rebar for reinforcing a new bridge: we will hope you have found a better way, but the burden of proof for explaining the superiority of your approach and proving that there are no hidden pitfalls is on you. 2 Coding standards for concurrent programs: 1.
    [Show full text]
  • Effective Inline-Threaded Interpretation of Java Bytecode
    Effective Inline-Threaded Interpretation of Java Bytecode Using Preparation Sequences Etienne Gagnon1 and Laurie Hendren2 1 Sable Research Group Universit´eduQu´ebec `a Montr´eal, [email protected] 2 McGill University Montreal, Canada, [email protected] Abstract. Inline-threaded interpretation is a recent technique that im- proves performance by eliminating dispatch overhead within basic blocks for interpreters written in C [11]. The dynamic class loading, lazy class initialization, and multi-threading features of Java reduce the effective- ness of a straight-forward implementation of this technique within Java interpreters. In this paper, we introduce preparation sequences, a new technique that solves the particular challenge of effectively inline-threa- ding Java. We have implemented our technique in the SableVM Java virtual machine, and our experimental results show that using our tech- nique, inline-threaded interpretation of Java, on a set of benchmarks, achieves a speedup ranging from 1.20 to 2.41 over switch-based inter- pretation, and a speedup ranging from 1.15 to 2.14 over direct-threaded interpretation. 1 Introduction One of the main advantages of interpreters written in high-level languages is their simplicity and portability, when compared to static and dynamic compiler-based systems. One of their main drawbacks is poor performance, due to a high cost for dispatching interpreted instructions. In [11], Piumarta and Riccardi introduced a technique called inlined-threading which reduces this overhead by dynamically inlining instruction sequences within basic blocks, leaving a single instruction dispatch at the end of each sequence. To our knowledge, inlined-threading has not been applied to Java interpreters before.
    [Show full text]