• Like
Message Passing Concurrency in Clojure using Kilim
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Message Passing Concurrency in Clojure using Kilim

  • 1,956 views
Published

 

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,956
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
16
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Kilim-Clojure integration Message Passing Concurrency in Clojure using Kilim Antonio Garrote Forward November 7, 2011
  • 2. Kilim-Clojure integrationClojure’s Concurrency Model JVM thread basic autonomous work unit Java shared memory explicit communication primitives Immutable data structures + implicit coordination mechanisms (STM, Refs)
  • 3. Kilim-Clojure integrationMessage Passing Communication 1 % T e r m i t e Scheme b e n c h m a r k s r i n g . e r l 2 m a k e r e l a y ( Next ) − > 3 receive 4 K when K > 0 − > 5 Next ! K − 1 , 6 m a k e r e l a y ( Next ) ; 7 K− > 8 Next ! K 9 end . 10 11 l o o p (K , C u r r e n t , N) when N > 1 − > 12 l o o p (K , spawn ( r i n g , m a k e r e l a y , [ C u r r e n t ] ) ,N − 1 ) ; 13 14 l o o p (K , C u r r e n t , ) −> 15 s e l f ( ) ! K, 16 make relay ( Current ) . 17 18 % N = number p r o c e s s e s 19 % K = number o f m e s s a g e e x c h a n g e s 20 r i n g (N, K) − > 21 l o o p (K , s e l f ( ) , N ) .
  • 4. Kilim-Clojure integrationMessage Passing Communication 1 2 N N = 100K , K = 0 518ms, 5µs process creation 3 K N = 100K , K = 1M 759ms, 0.76µs local msg . send. 4 6 5
  • 5. Kilim-Clojure integrationMessage Passing Communication How does Erlang do it? User level processes executing recursive functions VM preemptive scheduling One heap/stack per process, no global heap Tail call optimisation More predictable GC behaviour
  • 6. Kilim-Clojure integration Efficient implementation of message passing concurrency in the Java Virtual Machine?
  • 7. Kilim-Clojure integrationKilim “Kilim is a message-passing framework for Java that provides ultra-lightweight threads and facilities for fast, safe, zero-copy messaging between these threads” https://github.com/kilim/kilim 2006 Sriram Srinivasan, Opera Group Cambridge University Current version 0.72
  • 8. Kilim-Clojure integrationKilim Tasks Task 1 p u b l i c c l a s s ExampleTask e x t e n d s Task { 2 execute 3 p u b l i c void execute () throws Pausable { 4 doStuff ( ) ; 5 p u s a b l e S t u f f ( ) ; // t h r o w s P a u s a b l e Worker 6 moreStuff ( ) ; Thread 7 } 8 9 } notify Scheduler
  • 9. Kilim-Clojure integrationKilim Weaving: Bytecode Transformation Additional step after compilation Transforms pausable methods Creates a custom class to store the task state Associates a Fiber object, tracks task’s stack Transformed code returns immediately if the task is paused Worker threads can resume the execution of paused stacks unwinding the associated fiber stack
  • 10. Kilim-Clojure integrationKilim Weaving: Bytecode Transformation 1 p u b l i c void execute ( Fiber f i b e r ) throws Pausable { 2 s w i t c h ( f i b e r . pc ) { 3 c a s e 0 : g o t o START ; 4 c a s e 1 : g o t o PAUSABLE CALL ; 5 } 6 START : 7 doStuff ( ) ; 8 PAUSABLE CALL : 9 f i b e r . down ( ) ; 10 p u s a b l e S t u f f ( f i b e r ) ; // t h r o w s P a u s a b l e 11 f i b e r . up ( ) ; 12 switch ( f i b e r . status ) { 13 c a s e NOT PAUSING NO STATE : 14 g o t o RESUME ; 15 c a s e NOT PAUSING HAS STATE : 16 restoresState ( state ); 17 g o t o RESUME ; 18 c a s e PAUSING NO STATE : 19 captureState ( state ); 20 return ; 21 c a s e PAUSING HAS STATE : 22 return ; 23 } 24 RESUME : 25 moreStuff ( ) ; 26 }
  • 11. Kilim-Clojure integrationKilim Tasks: Execution Fiber.stack currentState StateObj.(1) Pausable() StateObj.(2) currentState down() StateObj.(3) Fiber Pausable() currentState down() Fiber Pausable() up() Pause Normal Return
  • 12. Kilim-Clojure integrationKilim Messages Buffered mailboxes Allows asynchronous communication between tasks Blocking / not blocking interface Polling interface
  • 13. Kilim-Clojure integrationKilim-Clojure Integration (first attempt) Modified version of Clojure’s compiler Clojure’s functions executed as Kilim’s tasks Weaving performed at run-time https://github.com/antoniogarrote/clojure/tree/kilim
  • 14. Kilim-Clojure integrationKilim-Clojure Integration (second attempt) Clojure library [clj-kilim ”0.2.0-SNAPSHOT”] Doc: http://antoniogarrote.github.com/clojure kilim/ Source: https://github.com/antoniogarrote/clojure kilim
  • 15. Kilim-Clojure integrationIntroduction Clojure Compiler Compiles bytecode Java Class Java instrumentation Kilim Weaved Java clj-kilim Weaver Class Bytecode Transformation Bytecode Transformation Class Loader
  • 16. Kilim-Clojure integrationKilim-Clojure Integration: API 1 ( d e f − p a u s a b l e y i e l d i n g − f n [ mbox ] 2 ( mbox−get−pausable mbox ) ) 3 4 5 ( def−pausable task−fn1 [ ] 6 ... 7 ( c a l l − p a u s a b l e y i e l d i n g − f n ambox ) 8 ...) 9 10 ( d e f task−fn2 ( p a u s a b l e [] ...)) 11 12 13 ( t a s k − s t a r t task−fn1 ) 14 ( t a s k − s t a r t task−fn2 )
  • 17. Kilim-Clojure integrationKilim-Clojure Integration Demo
  • 18. Kilim-Clojure integration Performance
  • 19. Kilim-Clojure integrationRing example again 1 ( d e f n ˆ { : p a u s a b l e t r u e } make−relay [ ˆ k i l i m . M a i l b o x s e l f 2 ˆ k i l i m . Mailbox next 3 ˆ k i l i m . Mailbox f i n a l ] 4 ( loop [ k ( r e c e i v e s e l f ) ] 5 ( i f (> k 0 ) 6 ( do 7 ( ! next ( dec k ) ) 8 ( recur ( . get s e l f ))) 9 ( do 10 ( ! next ( dec k ) ) 11 ( when ( n o t ( n i l ? f i n a l ) ) 12 (! f i n a l true )))))) 13 14 15 ( d e f n make−loop [ n k ] 16 ( l e t [ˆ k i l i m . Mailbox f i r s t − m a i l b o x ( k i l i m . Mailbox . ) 17 ˆ k i l i m . Mailbox final−mailbox ( k i l i m . Mailbox . ) ] 18 ( loop [ current first−mailbox 19 n n] 20 ( i f (> n 1 ) 21 ( recur 22 ( spawn ( p a u s a b l e [ ˆ k i l i m . M a i l b o x s e l f ] 23 ( make−relay s e l f c u r r e n t n i l ) ) ) 24 ( dec n ) ) 25 ( do ( spawn ( p a u s a b l e [ ˆ k i l i m . M a i l b o x ] 26 ( make−relay f i r s t − m a i l b o x c u r r e n t f i n a l − m a i l b o x ) ) ) 27 (! first−mailbox k) 28 ( . getb final−mailbox ) ) ) ) ) )
  • 20. Kilim-Clojure integrationPerformance N = 100K , K = 0 1264ms, 12µs process creation N = 100K , K = 1M 3276ms, 3µs local msg . send.
  • 21. Kilim-Clojure integrationConclusions Efficient message passing possible in the JVM thanks to Kilim Clojure can be a nice match for Kilim (immutable messages, run-time weaving) Benefits of asynchronous evented code with a nicer interface Limitations: non-preemptive Way to go? Improve performance Add distribution