+ All Categories
Home > Technology > Message Passing Concurrency in Clojure using Kilim

Message Passing Concurrency in Clojure using Kilim

Date post: 13-Jul-2015
Category:
Upload: antoniogarrote
View: 2,031 times
Download: 0 times
Share this document with a friend
Popular Tags:
21
Kilim-Clojure integration Message Passing Concurrency in Clojure using Kilim Antonio Garrote Forward November 7, 2011
Transcript
Page 1: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Message Passing Concurrency in Clojure usingKilim

Antonio Garrote

Forward

November 7, 2011

Page 2: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Clojure’s Concurrency Model

JVM thread basic autonomous work unit

Java shared memory explicit communication primitives

Immutable data structures + implicit coordinationmechanisms (STM, Refs)

Page 3: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Message Passing Communication

1 % Termite Scheme benchmarks r i n g . e r l2 make r e l a y ( Next ) −>3 r e c e i v e4 K when K > 0 −>5 Next ! K − 1 ,6 make r e l a y ( Next ) ;7 K −>8 Next ! K9 end .

1011 loop (K, Current , N) when N > 1 −>12 loop (K, spawn ( r i ng , make re l ay , [ Cu r r en t ] ) ,N − 1 ) ;1314 loop (K, Current , ) −>15 s e l f ( ) ! K,16 make r e l a y ( Cu r r en t ) .1718 % N = number p r o c e s s e s19 % K = number o f message exchanges20 r i n g (N, K) −>21 loop (K, s e l f ( ) , N) .

Page 4: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Message Passing Communication

1

5

3

N2

4 6

K

N = 100K ,K = 0518ms, 5µs process creation

N = 100K ,K = 1M759ms, 0.76µs local msg . send .

Page 5: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Message 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

Page 6: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Efficient implementation of message passing concurrency in theJava Virtual Machine?

Page 7: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim

“Kilim is a message-passing framework for Java that providesultra-lightweight threads and facilities for fast, safe, zero-copymessaging between these threads”

https://github.com/kilim/kilim

2006 Sriram Srinivasan, Opera Group Cambridge University

Current version 0.72

Page 8: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim Tasks

1 p u b l i c c l a s s ExampleTask ex t end s Task {23 p u b l i c vo i d e x e cu t e ( ) throws Pausab l e {4 doS tu f f ( ) ;5 p u s a b l e S t u f f ( ) ; // throws Pausab l e6 moreStu f f ( ) ;7 }89 }

Task

Worker

Thread

Scheduler

notify

execute

Page 9: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim 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 stacksunwinding the associated fiber stack

Page 10: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim Weaving: Bytecode Transformation

1 p u b l i c vo i d e x e cu t e ( F i b e r f i b e r ) throws Pausab l e {2 sw i t ch ( f i b e r . pc ) {3 ca se 0 : goto START;4 ca se 1 : goto PAUSABLE CALL ;5 }6 START:7 doS tu f f ( ) ;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 ) ; // throws Pausab l e11 f i b e r . up ( ) ;12 sw i t c h ( f i b e r . s t a t u s ) {13 case NOT PAUSING NO STATE :14 goto RESUME;15 ca se NOT PAUSING HAS STATE :16 r e s t o r e s S t a t e ( s t a t e ) ;17 goto RESUME;18 ca se PAUSING NO STATE :19 c ap t u r eS t a t e ( s t a t e ) ;20 r e t u r n ;21 ca se PAUSING HAS STATE :22 r e t u r n ;23 }24 RESUME:25 moreStu f f ( ) ;26 }

Page 11: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim Tasks: Execution

Pausable()

Fiber Pausable()

Fiber Pausable()

down()

down()

StateObj.(1)

StateObj.(2)

StateObj.(3)

Fiber.stack

currentState

currentState

currentState

Pause Normal Return

up()

Page 12: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim Messages

Buffered mailboxes

Allows asynchronous communication between tasks

Blocking / not blocking interface

Polling interface

Page 13: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim-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

Page 14: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim-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

Page 15: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Introduction

Java Class

Clojure Compiler

Compiles bytecode

clj-kilim

Java instrumentation

Kilim Weaver

Bytecode Transformation

Class Loader

Weaved Java Class

Bytecode Transformation

Page 16: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim-Clojure Integration: API

1 ( def−pausab le y i e l d i n g− f n [ mbox ]2 (mbox−get−pausable mbox ) )345 ( def−pausab le task− fn1 [ ]6 . . .7 ( c a l l−pau sab l e y i e l d i n g− f n ambox )8 . . . )9

10 ( de f task− fn2 ( pau sab l e [ ] . . . ) )111213 ( t a sk− s t a r t task− fn1 )14 ( t a sk− s t a r t task− fn2 )

Page 17: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Kilim-Clojure Integration

Demo

Page 18: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Performance

Page 19: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Ring example again1 ( de fn ˆ{ : p au sab l e t r u e} make−relay [ ˆ k i l i m . Mai lbox s e l f2 ˆ k i l i m . Mai lbox next3 ˆ k i l i m . Mai lbox f i n a l ]4 ( l oop [ k ( r e c e i v e s e l f ) ]5 ( i f (> k 0)6 ( do7 ( ! nex t ( dec k ) )8 ( r e c u r ( . ge t s e l f ) ) )9 ( do

10 ( ! nex t ( dec k ) )11 (when ( not ( n i l ? f i n a l ) )12 ( ! f i n a l t r u e ) ) ) ) ) )131415 ( de fn make−loop [ n k ]16 ( l e t [ ˆ k i l i m . Mai lbox f i r s t−ma i l b o x ( k i l i m . Mai lbox . )17 ˆ k i l i m . Mai lbox f i n a l−ma i l box ( k i l i m . Mai lbox . ) ]18 ( l oop [ c u r r e n t f i r s t−ma i l b o x19 n n ]20 ( i f (> n 1)21 ( r e c u r22 ( spawn ( pau sab l e [ ˆ k i l i m . Mai lbox 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 ( pau sab l e [ ˆ k i l i m . Mai lbox ]26 ( make−relay f i r s t−ma i l b o x c u r r e n t f i n a l−ma i l box ) ) )27 ( ! f i r s t−ma i l b o x k )28 ( . getb f i n a l−ma i l box ) ) ) ) ) )

Page 20: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Performance

N = 100K ,K = 01264ms, 12µs process creation

N = 100K ,K = 1M3276ms, 3µs local msg . send .

Page 21: Message Passing Concurrency in Clojure using Kilim

Kilim-Clojure integration

Conclusions

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 performanceAdd distribution


Recommended