1. Share and Share AlikeUsing System V shared memory constructs inMRI Ruby projects
2. Who Am I? Jeremy Holland Senior Lead Developer at CentreSource in beautiful Nashville, TN Math and Algorithms nerd Scotch drinker @awebneck, github.com/awebneck, freenode: awebneck, etc.
3. The Problem FREAKIN HUGE BINARY TREE
4. How huge? Huge. Millions of nodes, each node holding ~500 bytes e.g. Gigabytes of data K-d tree of non-negligible dimension (varied, around 6-10) No efficient existing implementation that would serve the purposes needed Fast search Reasonably fast consistency
5. Things we considered ...and discarded Index the tree, persist to disk Loading umpteen gigs of data from disk takes a spell. Reload it for each query WAY TOO SLOW
6. Things we considered ...and discarded Index once and hold in memory Issues both with maintaining index consistency and balance Difficult to share among many processes / threads without duplicating in memory.
7. Things we considered ...and discarded DRb Simulates memory shared by multiple processes, but not really While the interface to search the tree is available to many different processes, actually searching it takes place in the single, server-based process
8. Enter Shared Memory Benefits Shared segment actually accessible by multiple, wholly separate processes Built-in access control and permissions Built-in per-segment semaphore Drawbacks With great power comes great responsibility Acts like a bytearray manual serialization
9. Ruby-level memory paradigm vs C-level memory paradigm Ruby: Everything goes on the heap Garbage collected - no explicit freeing of memory C: Local vars, functions, etc. on the stack Explicit allocations on the heap (malloc) Explicit freeing of heap no GC
10. Ruby Before start of process
11. Ruby Process starts Heap begins to grow
12. Ruby Process runs Heap continues to grow with additional allocations
13. Ruby Process runs GC frees allocated memory no longer needed...
14. Ruby ...so it can be reallocated for new objects
15. Ruby Process ends Heap freed
16. C Process starts Stack grows to hold functions, local vars
17. C Process runs Memory is explicitly allocated from the heap in the form of arrays, structs, etc.
18. C Process runs A function is called, and goes on the stack
19. C Process runs The function returns, and is popped off the stack
20. C Process runs The item in the heap, no longer needed, is explicitly freed
21. C Process runs A new array is allocated from the heap
22. C Process ends (untidily) The stack and heap are reclaimed by the OS as free
23. TRUTHRuby itself has no concept of shared memory.
24. TRUTH C does.
25. Shared Memory A running process (as viewed from the C level)
26. Shared Memory A shared segment is created with an explicit size like allocating an array
27. Shared Memory The segment is attached to the process at a virtual address
28. Shared Memory Yielding to the process a pointer to the beginning of the segment
29. Shared Memory A new process starts, wishing to attach to the same segment.
30. Shared Memory It asks the OS for the identifier of the segment based on an integer key Are you there? Yup!
31. Shared Memory ...and attaches it to itself in fashion similar to the original.
32. Shared Memory Both processes can now - depending on permissions read and write from the segment simultaneously!
33. Shared Memory The first process finishes with the segment and detaches it.
34. Shared Memory And thereafter, ends.
35. Shared Memory ...leaving only the second process, still attached
36. Shared Memory Now, the second process detaches...
37. Shared Memory ...and subsequently ends
38. Shared Memory Note that the shared segment is still in persisted in memory Can be reattached t