Like the title says, I'm looking for a way to efficiently share some data across embarrassingly parallel workloads without having to pay the communication cost of sending data through channels or locking it. I'm thinking mostly of (parallel) threads, futures, and places here.
Context
Some years ago I worked on a "mosaic" program. The implementation is mostly Matlab code dealing with ARGB images, and I'd like to reimplement it with a GUI. If I have to do the image parts in Rust for efficiency, I'm willing to try it, but I think math/array
- or fxvector
- style code ought to be just fine.
As a rough sketch, the program takes in one large image and many smaller ones, replacing sections of the large image with similar small images. That creates the mosaic.
My plan now—to avoid sending tons of data back and forth—is to have the parallelism communicate "replace block (i, j)
with small image p
." That is, to use IDs rather than the bytes themselves. That also means only one thread (or place, or future…) needs to write into an output buffer.
So theoretically all the other parallelism only needs to read a bunch of shared data that won't mutate out from under it. I'm interested in trying out the new parallel threads for this project, but I think futures or places would work just as well as long as I had efficient (lock-free?) access to the data.
Does this… just work? My understanding of shared memory in Racket is hazy, since communicating processes (concurrent threads + message passing) is so easy to do correctly. In Rust for example I know how to structure parallel threads to borrow references to immutable data (and give a single thread mutable access to an object), so that guarantees the sort of lock-free efficient properties I'm after. But building GUIs is so much nicer with Racket
and I don't really want to start by rewriting the numerics code in Rust, yet.
With immutable shared data, and certainly with bytes or fxvectors, you should be able to just share it among futures and the forthcoming parallel threads.
For places, you would need to communicate over place channels with place-message-allowed?
values, which (at least conceptually) copies immutable values, except for a few special cases that can explicitly share memory, like make-shared-bytes
. I would think the new parallel threads, or possibly futures, would be a better fit for this than places.
1 Like
This looks like an interesting project!
If performance does become a problem, let me know before you reach for rust. I'm working on a numpy-like library for racket and I'm interested in potential use cases. The backend is written in C using openmp for parallelism, but I want the racket side to be full featured enough that most users won't need to know C. Of course, by using the FFI the library will be unsafe.
Anyway, have fun porting this to racket. I've found that futures are pretty easy to use and so are the new parallel threads, from what little I've done with them so far.
1 Like
With immutable shared data, and certainly with bytes or fxvectors, you should be able to just share it among futures and the forthcoming parallel threads.
Excellent! That's what I figured, but after writing threaded Rust for a week my memories of Racket's model got turned inside out 
I would think the new parallel threads, or possibly futures, would be a better fit for this than places.
Agreed 
This looks like an interesting project!
Thanks! It was fun the first time, too.
If performance does become a problem, let me know before you reach for rust. I'm working on a numpy-like library for racket and I'm interested in potential use cases. The backend is written in C using openmp for parallelism, but I want the racket side to be full featured enough that most users won't need to know C. Of course, by using the FFI the library will be unsafe.
Yes, I'm hoping to use some kind of numerics library (math/array
? Something else?), but I'll reach out if that doesn't end up working. FWIW, I recall running overnight to process ~17 mosaics at a time with varying (but typically a few thousand) sub-images to choose from. No parallelism there, though. I'm hoping to get to something that is closer to "interactive."
Anyway, have fun porting this to racket. I've found that futures are pretty easy to use and so are the new parallel threads, from what little I've done with them so far.
Excellent! This will be my first foray into futures
It's easier for me to think about structuring the work with a thread pool that I feed jobs too, though. I'll have to review the futures API a bit.
1 Like